你好,我有一段运行协程的代码。我正在尝试为它编写单元测试。但似乎失败了。我已经添加了协程测试规则来添加StandardTestDispatcher,但我猜这似乎不起作用。任何想法都非常感谢。我第一次尝试为协程编写单元测试,但卡住了。
下面是我的简单演示者类,它使用协程
class PostsActivityPresenter(
private val apiHelper: ApiFactory
) : CoroutineScope, PostsContract.Presenter {
private var view: PostsContract.View? = null
private val job: Job = Job()
override val coroutineContext: CoroutineContext = job + Dispatchers.IO
override fun attachView(view: PostsContract.View?) {
this.view = view
}
override fun getPostsandUserInfo() {
launch {
val posts = apiHelper.getPosts()
val users = apiHelper.getUsers()
val postsWithUserDetails = mutableListOf<PostsWithUserInfo>()
for (post in posts) {
users.firstOrNull { it.id == post.userId }?.let { user ->
postsWithUserDetails.add(PostsWithUserInfo(post, user))
}
}
withContext(Dispatchers.Main) { ///// Test will pass if this line is removed.
view?.displayPosts(postsWithUserDetails)
}
}
}
override fun detachView() {
job.cancel()
view = null
}
}
下面是我单元测试代码:
class PostsPresenterTest {
@RelaxedMockK
private lateinit var apiHelper: ApiHelper
@io.mockk.impl.annotations.MockK
private lateinit var view: PostsContract.View
@ExperimentalCoroutinesApi
@get:Rule
var coroutinesTestRule = CoroutineTestRule()
private lateinit var subject: PostsActivityPresenter
private val posts = listOf(
Post(
id = 1,
userId = 12,
title = "title 1",
body = "body 1"
)
)
private val users = listOf(
User(
name = "Name1",
username = "Username1",
email = "email1@gmail.com",
id = 12
),
User(
name = "Name2",
username = "Username2",
email = "email2@gmail.com",
id = 13
)
)
@Before
fun setUp() {
MockKAnnotations.init(this, relaxed = true)
subject = PostsActivityPresenter((apiHelper))
}
@ExperimentalCoroutinesApi
@Test
fun `test if posts is being called`() = runBlocking {
// arrange
coEvery { apiHelper.getPosts() }.returns(posts)
coEvery { apiHelper.getUsers() }.returns(users)
every { view.displayPosts(any()) }.returns(Unit)
// act
subject.attachView(view)
subject.getPostsandUserInfo()
// assert
coVerify {
view.displayPosts(
listOf(
PostsWithUserInfo(
post = Post(
userId = 12,
id = 1,
title = "title 1",
body = "body 1"
),
user = User(
id = 12,
name = "Name1",
username = "Username1",
email = "email1@gmail.com",
)
)
)
)
}
}
}
@ExperimentalCoroutinesApi
class CoroutineTestRule(private val testDispatcher: TestDispatcher = StandardTestDispatcher()) : TestWatcher() {
override fun starting(description: Description) {
super.starting(description)
Dispatchers.setMain(testDispatcher)
}
override fun finished(description: Description) {
super.finished(description)
Dispatchers.resetMain()
testDispatcher.cleanupTestCoroutines()
}
}
1条答案
按热度按时间jdgnovmf1#
将你的测试调度器= StandardTestDispatcher()改为testCoroutineDispatcher = UnconfinedTestDispatcher(),这对我来说非常有效。