java - 将模拟对象提供给另一个模拟对象构造函数?

标签 java android unit-testing kotlin mockito

第一次单元测试,并使用 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/

相关文章:

java - 使用 Spring 和 JWT 基于 token 的身份验证

java - 如何在 querydsl 中使用别名?

java - Android NDK 相机路径 getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)

unit-testing - 如何为 AngularJS 模型编写单元测试

java - 以编程方式找出有多少对象符合垃圾收集条件?

java - JAVA 中的 OOP - Android

android - 如何在 Kotlin 的 Fragment 中使用 Android AlarmManager?

android - 构建xamarin android项目失败,错误XA4212

c# - OO 中的单元测试和访问修饰符

java - 通过 Hamcrest 断言集合中匹配元素的数量