第一次单元测试,并使用 Mockito。我不确定我是否正在考虑正确地测试它。这是情况:
在我的 Android 应用中,我使用的是 Model-View-Presenter。我正在尝试在我的 Presenter 类中测试一个名为 validateCredential(serviceManager: ServiceManager, email: String, password: String)
的方法,看看我传递给它的服务管理器是否最终会调用回调(这个方法由 View 调用)通过使用 mockito 验证它。
// method in presenter class
override fun validateCredential(serviceManager: ServiceManager, email: String, password: String) {
loginModel = LoginModel(email, password)
serviceManager.getParent(email, password)
serviceManager.execute()
}
// callback implemented by presenter class
private fun handleLoginResult(result: ServiceManager.RequestResult, data: ByteArray, responseCode: Int, optionalParam: String) {
...
mView.startHomeScreen()
}
presenter 类还实现了提供给 serviceManager
构造函数的回调接口(interface) (IServiceAsyncTaskCallback
)。在这个特定的单元测试中,我想要的是验证是否调用了 mView.startHomeScreen()
。
问题:
- Android 单元测试似乎需要模拟 ServiceManager(ServiceManager 扩展抽象类 AsyncTask),因为当我调用
execute()
时,如果未模拟,Android 单元测试库将抛出异常。 - 但是,如果我模拟 ServiceManager,我无法为构造函数提供两个必要的参数,如果我正确理解单元测试,应该模拟这些参数。构造函数的两个参数是一个接口(interface)回调(即presenter类),以及一个负责通过http发送JSON的类对象。这两个都应该被 mock ,对吗?因为在单元测试中,您不希望这些依赖项实际进行 HTTP 调用或调用回调,对吗?
- 看来我想多了。我真正想要的是查看传递给演示者的 View 对象是否调用
startHomeScreen()
,所以我真的应该忘记测试validateCredentialMethod()
并调用handleLoginResult(...)
直接。这比上面的路线好吗? - 然而,另一个问题是,即使我直接调用
handleLoginResult(...)
来测试是否调用了传递给演示者的模拟 View ,该方法代码包含对 JSONObject 的调用,它是Android相关的代码,由于属于android.jar文件,所以会因为没有mocked而抛出异常!我也应该为此注入(inject)吗?!
我不知道如何测试这个。验证模拟 View 是否已调用 startHomeScreen()
的正确方法是什么?
最佳答案
问题是您试图在一个单元测试中测试两个单独的类,这使其不是单元测试。
根据您当前的设置,您似乎希望在 2 个不同的类中有 3 个不同的测试用例(编造名称,尽量明确其内容):
演示者测试
- testThatServiceManagerIsExcecutedOnValidateCredential
- testThatStartHomeScreenIsCalledWhenHandlingLoginResult
服务管理器测试
- testCallbackIsCalledOnExcecuted
关于java - 将模拟对象提供给另一个模拟对象构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47321131/