嗨,我试图模仿我从一个可以观察到的单个响应中得到的响应,这个响应是通过使用我的演示类调用的委托程序返回的,并且我得到了以下错误:
LoginPresenter(#1).login(LoginRequest(email=hello@gmail.com,io.mockk.MockKException: io.mockk.MockKException:找不到答案)
这是我的测试代码
@Test
fun testKotlinMock(){
val presenter : LoginPresenter = mockk<LoginPresenter>()
val delegator = mockk<AccountDelegatorContract>()
val viewCallback = mockk<LoginContract.LoginViewCallBack>()
val cookieStore = mockk<PianoCookieStore>()
val loginRequest = LoginRequest("hello@gmail.com", "password123")
val customerResponse = CustomerResponse("jon", "richy")
every { delegator.login(loginRequest) } returns Single.just(Response.success(any()))
every { delegator.getCustomer() } returns Single.just(customerResponse)
every { presenter.loginViewCallBack } returns viewCallback
every { presenter.accountDelegator } returns delegator
every { presenter.cookieStorage } returns cookieStore
presenter.login(loginRequest)
}我的实际演示代码如下所示:
@Inject
lateinit var loginViewCallBack: LoginViewCallBack
@Inject
lateinit var delegator: DelegatorContract
@Inject
lateinit var cookieStorage: CookieStore
@Inject
constructor()
override fun login(loginRequest: LoginRequest) {
delegator.login(loginRequest)
.flatMap({ response ->
saveCookieAndContinue(response)
})
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(object : SingleObserver<CustomerResponse>{
override fun onSubscribe(d: Disposable) {
}
override fun onError(e: Throwable) {
loginViewCallBack.onErrorLogin(PianoError.ERROR_LOGIN_INVALID)
Log.d("JJJ", "login error")
}
override fun onSuccess(customerResponse : CustomerResponse) {
loginViewCallBack.onLoginSuccess(customerResponse)
Log.d("JJJ", "login successfully")
}
})
}
private fun saveCookieAndContinue(response: Response<Void>): Single<CustomerResponse> {
if (response.isSuccessful) {
val headers = response.headers()
cookieStorage.saveSessionCookies(headers.get(PianoCookieStore.COOKIE_HEADER_SET_NAME)!!)
return accountDelegator.getCustomer()
}
//TODO: Change this to throw a login exception?
throw RuntimeException()
}基本上,我希望模拟从主代码中看到的注入依赖项,然后运行一个愉快的路径单元测试。
当我调用presenter.login(loginRequest)时,如果没有找到答案,它就会失败
这是我使用http://mockk.io/的kotlin扩展插件
发布于 2018-01-25 06:23:51
在您的例子中,您模拟了正在测试的类。你有两个选择:
spyk创建间谍。这是介于原始对象和模拟之间的东西。例外情况是抛出,因为默认情况下模拟是严格的,它只是不知道如何处理它,因为模拟作为对象根本没有初始化。
在这里阅读更多关于模拟、间谍和轻松模仿的内容:https://blog.kotlin-academy.com/mocking-is-not-rocket-science-mockk-features-e5d55d735a98
发布于 2019-01-18 05:43:05
首先,我建议您调试测试。然后,您将发现代码的哪一行运行失败。我对您也有同样的经验,但在我的例子中,我的测试在onSuccess上时失败了,例如,从您的代码中可以看出:
override fun onSuccess(customerResponse : CustomerResponse) {
loginViewCallBack.onLoginSuccess(customerResponse)
Log.d("JJJ", "login successfully")
}我认为您的测试在到达loginViewCallBack.onLoginSuccess(customerResponse)行后会失败,因为在模拟测试中找不到loginViewCallback。如果您有要模拟的接口类,则应该将其编写为:
@RelaxedMockK
lateinit var viewCallback: LoginContract.LoginViewCallBack在我的例子中,在我用轻松的模拟更改了这个接口之后,错误not answer found error就解决了。
在文档:轻松的模拟中,模拟返回所有函数的一些简单值。这允许跳过为每种情况指定行为,同时仍然允许对所需的内容进行存根。对于引用类型,将返回链式模拟。
发布于 2022-04-01 15:45:23
在我的例子中,我忘记检查是否调用了一个方法(例如,在代码中我们有object.setData(person.getAge()))。
every { object.setData(any()) } just Runs // Mock method
testedMethod() // Tested code runs here
verify { object.setData(any()) } // Check that object.setData() was calledhttps://stackoverflow.com/questions/48223513
复制相似问题