Ios Xcode-为运行和测试操作设置不同的类

Ios Xcode-为运行和测试操作设置不同的类,ios,xcode,Ios,Xcode,我正在开发iOS应用程序(使用Objective-C和Xcode),目前我正在尝试为运行操作和测试操作设置不同的类,但到目前为止还无法实现。 让我们设想有一个targetA和一个单元测试的target,我们称它为A_UnitTest(A_UnitTest测试targetA)。 有一个类负责登录过程,让我们调用它LoginManager,它有方法login,这个方法负责登录到真实系统。还有一个类用于使用与LoginManager相同的名称和相同的接口进行假登录,它应该仅用于测试目的 在运行操作期间

我正在开发iOS应用程序(使用Objective-C和Xcode),目前我正在尝试为运行操作和测试操作设置不同的类,但到目前为止还无法实现。 让我们设想有一个targetA和一个单元测试的target,我们称它为A_UnitTestA_UnitTest测试targetA)。 有一个类负责登录过程,让我们调用它LoginManager,它有方法login,这个方法负责登录到真实系统。还有一个类用于使用与LoginManager相同的名称和相同的接口进行假登录,它应该仅用于测试目的

在运行操作期间,targetA连接了realLoginManager类,并且所有类都工作得很好,但是在测试操作期间(当选择了A\u UnitTest时),我运行单元测试-我想测试targetA我想使用假的LoginManager。我可以手动选择fakeLoginManager作为目标A(取消选择realLoginManager并选择fakeLoginManager作为目标A),但我希望它能自动工作。我的意思是,我只想选择targetA_UnitTest和test targetA,但在测试过程中,我希望应该使用假的LoginManager而不是真正的LoginManager。你知道我是否可以在Xcode中实现这一点吗?或者我应该在行动前的步骤中加入一些脚本


谢谢你的帮助

我不认为你想要实现的目标是可能的(至少很容易)。
您应该做的是,以一种可以注入依赖项的方式构造代码,然后您可以在测试中使用生产类的模拟版本

简单示例(在Swift中,因为没有语言标记):

制作:

protocol LoginManagerProtocol {
    func loginWithCredentials(login: String, password: String)
}

class LoginManager: LoginManagerProtocol {

    func loginWithCredentials(login: String, password: String) {
        // perform your production login here
    }
}

class LoginViewModel {
    private let loginManager: LoginManagerProtocol

    init(loginManager: LoginManagerProtocol) {
        self.loginManager = loginManager
    }

    func loginUser(with login: String, password: String) {
        loginManager.loginWithCredentials(login: login, password: password)
    }
}
测试:

class LoginManagerMock: LoginManagerProtocol {

    var mock_loginWithCredentials: ((String, String) -> Void)?
    func loginWithCredentials(login: String, password: String) {
        mock_loginWithCredentials?(login, password)
    }
}

class LoginViewModelTests: XCTest {

    func test_loginUser_shouldPassCredentials_toLoginManager() {
        // Arrange
        let sampleLogin = "login"
        let samplePassword = "password"

        let loginManagerMock = LoginManagerMock()
        var capturedCredentials: (login: String, password: String)?

        loginManagerMock.mock_loginWithCredentials = { login, password in 
            capturedCredentials = (login, password)
        }

        // Act
        let sut = LoginViewModel(loginManager: loginManagerMock)
        sut.loginUser(with: sampleLogin, password: samplePassword)

        // Assert
        XCTAssertEqual(sampleLogin, capturedCredentials.login)
        XCTAssertEqual(samplePassword, capturedCredentials.password)
    }
}
如果您使用的是Objective-C,那么可以使用类似的方法,或者您可以使用一个模拟库(例如)