请在下面找到一个使用协程替换回调的函数:
override suspend fun signUp(authentication: Authentication): AuthenticationError {
return suspendCancellableCoroutine {
auth.createUserWithEmailAndPassword(authentication.email, authentication.password)
.addOnCompleteListener(activityLifeCycleService.getActivity()) { task ->
if (task.isSuccessful) {
it.resume(AuthenticationError.SignUpSuccess)
} else {
Log.w(this.javaClass.name, "createUserWithEmail:failure", task.exception)
it.resume(AuthenticationError.SignUpFail)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想对这个函数进行单元测试。我正在使用 Mockk :
@Test
fun `signup() must be delegated to createUserWithEmailAndPassword()`() = runBlockingTest {
val listener = slot<OnCompleteListener<AuthResult>>()
val authentication = mockk<Authentication> {
every { email } returns "email"
every { password } returns "pswd"
}
val task = mockk<Task<AuthResult>> {
every { isSuccessful } returns true
} …
Run Code Online (Sandbox Code Playgroud) 我需要检查单元测试中是否未调用某个方法。这是我所做的一个示例测试,用于检查该方法是否被调用并且它工作得很好:
@Test
fun viewModel_selectDifferentFilter_dispatchRefreshAction() {
val selectedFilter = FilterFactory.make()
val event = GroceriesAisleFiltersUiEvent.SelectFilter(
filter = selectedFilter,
refreshListAction = mockk()
)
every { event.refreshListAction(selectedFilter) } just runs
viewModel.dispatchViewAction(event)
verify { event.refreshListAction(selectedFilter) }
}
Run Code Online (Sandbox Code Playgroud)
为此,我使用 mockk 的verify
函数来检查该方法是否被调用。
有没有办法使用 检查mockk
该方法是否未被调用?简而言之,我需要用此检查代替注释来完成下面的代码:
@Test
fun viewModel_selectSameFilter_notDispatchRefreshAction() {
val selectedFilter = viewModel.viewState.value.selectedFilter
val event = GroceriesAisleFiltersUiEvent.SelectFilter(
filter = selectedFilter,
refreshListAction = mockk()
)
every { event.refreshListAction(selectedFilter) } just runs
viewModel.dispatchViewAction(event)
// TODO: verify if method's not invoked
}
Run Code Online (Sandbox Code Playgroud) 我想实现一些 UI 测试,以确保今天实现的代码明天也能正常工作,但是当尝试查看过去实现的 UI 测试是否有效时,它会抛出此错误:
Caused by: io.mockk.MockKException: Failed matching mocking signature for left matchers: [any(), any()]
这种情况发生在every {} return Unit
有一个名为 WakeUpTimeManager 的对象文件的行上,该文件调用 .set(param1, param2)函数,并且在该函数内部有一些内联函数,我认为这可能会导致问题,但我不知道。我尝试在互联网上搜索但找不到解决方案。
这是引发错误的测试:
@Before
fun setup() {
mockkObject(WakeUpTimerManager)
every { WakeUpTimerManager.set(any(), any()) } returns Unit
}
Run Code Online (Sandbox Code Playgroud)
every
这是在线调用的函数
fun set(context: Context, timer: Timer) {
if (timer.atMillis < System.currentTimeMillis()) {
return
}
if (Preset.findByID(context, timer.presetID) == null) {
return
}
//This is an inline function
withGson {
PreferenceManager.getDefaultSharedPreferences(context).edit {
putString(PREF_WAKE_UP_TIMER, …
Run Code Online (Sandbox Code Playgroud) 嗨,我正在尝试模拟我从使用我的演示者类调用的委托者从改造中返回的单个可观察对象获得的响应,并且出现以下错误:
io.mockk.MockKException:没有找到答案:LoginPresenter(#1).login(LoginRequest(email=hello@gmail.com, password=password123))
这是我的测试代码
@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)
}
Run Code Online (Sandbox Code Playgroud)
我的实际演示者代码如下所示:
@Inject
lateinit var loginViewCallBack: LoginViewCallBack
@Inject
lateinit var delegator: DelegatorContract
@Inject
lateinit …
Run Code Online (Sandbox Code Playgroud) 找不到有关“just run”的解释,用它存根函数时意味着什么?
它会让模拟对象调用它的真实函数,还是让该函数运行一个不执行任何操作的存根?
是否有示例来展示一些真实的用例?
@Test
fun `mocking functions that return Unit`() {
val SingletonObject = mockkObject<SingletonObject>()
every { SingletonObject.functionReturnNothing() } just Runs. // ???
SingletonObject.otherMemberFunction(). //which internally calls functionReturnNothing()
//...
}
Run Code Online (Sandbox Code Playgroud)
无论有没有这个every { SingletonObject.functionReturnNothing() } just Runs
存根,测试都是一样的。
我正在为我的数据存储库层编写一个单元测试,它只是调用一个接口。我使用 Kotlin、协程和 MockK 进行单元测试。在MockK中,我如何验证我已经调用过apiServiceInterface.getDataFromApi()
并且只发生过一次?我应该将代码放在 runBlocking 中吗?
这是我的代码:
单元测试
import com.example.breakingbad.api.ApiServiceInterface
import com.example.breakingbad.data.DataRepository
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import io.mockk.verify
import org.junit.Test
Run Code Online (Sandbox Code Playgroud)
存储库
class DataRepositoryTest {
@MockK
private lateinit var apiServiceInterface: ApiServiceInterface
@InjectMockKs
private lateinit var dataRepository: DataRepository
@Test
fun getCharacters() {
val respose = dataRepository.getCharacters()
verify { apiServiceInterface.getDataFromApi() }
}
}
class DataRepository @Inject constructor(
private val apiServiceInterface: ApiServiceInterface
) {
suspend fun getCharacters(): Result<ArrayList<Character>> = kotlin.runCatching{
apiServiceInterface.getDataFromApi()
}
}
Run Code Online (Sandbox Code Playgroud)
界面
interface ApiServiceInterface {
@GET("api/characters")
suspend fun getDataFromApi(): ArrayList<Character> …
Run Code Online (Sandbox Code Playgroud) 我阅读了文档,但我仍然不明白。
这之间的差异
private val myClass: MyClass = mockk(relaxed = true)
Run Code Online (Sandbox Code Playgroud)
和这个。
private val myClass: MyClass = mockk()
Run Code Online (Sandbox Code Playgroud)
我的理解是如果放松是真的。然后,所有成员字段或方法都将返回默认值。否则,不会。这是正确的理解吗?
如果是这样,设置alwaysrelaxed=true会更好。但在这段视频中,瑞安同时使用了两者。为什么?
我刚刚开始使用MockK在基于 MVP 的应用程序中模拟所有存储库/服务逻辑以进行 UI 测试。
我有一些运行登录活动的 UI 测试,其中 Espresso 输入登录名和密码,并使用 MockK 我可以伪造登录失败与否的各种情况。
所有服务和存储库都是标准的 Kotlin 对象,所以我使用mockkobject
和every/coEvery
来覆盖和处理登录请求和任务。
在我的物理设备上,测试完全没有问题,但是一旦我尝试在运行 Android P+ 并带有推荐图像的模拟器上运行它们,它们就会在随机时间不断崩溃。在极少数情况下,它们可以存活足够长的时间来工作。
查看日志,我得到了各种 SIGSEGV:
A/libc:致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 10425 (e.android.debug) 中的故障地址 0x0,pid 10425 (e.android.debug)
A/libc:致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 10968 (HeapTaskDaemon) 中的故障地址 0xc,pid 10957 (e.android.debug)
A/libc:致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 15050 中的故障地址 0x0 (firebase-instal),pid 14972 (e.android.debug)
A/libc:致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 8902 中的故障地址 0xd (Measurement Wor),pid 8858 (e.android.debug)
A/libc:致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 22004 …
当先前的方法调用抛出异常时,我需要验证是否未进行某个调用。
// GIVEN
every { relaxedMock.eats() }.throws(NotHungryException())
// WHEN
sut.live()
// THEN
verify (exactly = 0) { relaxedMock2.sleeps() }
Run Code Online (Sandbox Code Playgroud)
这段代码有问题,它失败是因为抛出异常,而不是因为验证失败。
我们目前正在使用带有kotlin项目的java,慢慢地将整个代码迁移到后者.
是否可以模拟静态方法,如Uri.parse()
使用Mockk?
示例代码如何?
kotlin ×10
mockk ×10
android ×6
unit-testing ×5
java ×1
junit ×1
mocking ×1
mockito ×1
mockk-verify ×1
static ×1