Gần đây đã được giới thiệu lớp học StateFlownhư một phần của chương trình đăng quang Kotlin.
Tôi hiện đang dùng thử nó và gặp sự cố khi cố gắng kiểm tra đơn vị ViewModel của mình. Điều tôi muốn đạt được: kiểm tra xem của tôi StateFlowcó đang nhận tất cả các giá trị trạng thái theo đúng thứ tự trong ViewModel của tôi không.
Mã của tôi như sau:
ViewModel:
class WalletViewModel(private val getUserWallets: GetUersWallets) : ViewModel() {
val userWallet: StateFlow<State<UserWallets>> get() = _userWallets
private val _userWallets: MutableStateFlow<State<UserWallets>> =
MutableStateFlow(State.Init)
fun getUserWallets() {
viewModelScope.launch {
getUserWallets.getUserWallets()
.onStart { _userWallets.value = State.Loading }
.collect { _userWallets.value = it }
}
}
Bài kiểm tra của tôi:
@Test
fun `observe user wallets ok`() = runBlockingTest {
Mockito.`when`(api.getAssetWallets()).thenReturn(TestUtils.getAssetsWalletResponseOk())
Mockito.`when`(api.getFiatWallets()).thenReturn(TestUtils.getFiatWalletResponseOk())
viewModel.getUserWallets()
val res = arrayListOf<State<UserWallets>>()
viewModel.userWallet.toList(res) //doesn't works
Assertions.assertThat(viewModel.userWallet.value is State.Success).isTrue() //works, last value enmited
}
Truy cập giá trị cuối cùng được phát ra hoạt động. Nhưng những gì tôi muốn kiểm tra là tất cả các giá trị phát ra được phát ra theo đúng thứ tự. với đoạn mã này: viewModel.userWallet.toList(res) //doesn't worksTôi gặp lỗi sau:
java.lang.IllegalStateException: This job has not completed yet
at kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1189)
at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:53)
at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest$default(TestBuilders.kt:45)
at WalletViewModelTest.observe user wallets ok(WalletViewModelTest.kt:52)
....
Tôi đoán tôi đang thiếu một cái gì đó rõ ràng. Nhưng không chắc tại sao vì tôi mới bắt đầu với Coroutine và Flow và lỗi này dường như xảy ra khi không sử dụng runBlockingTest mà tôi đã sử dụng.
CHỈNH SỬA: Là một giải pháp tạm thời, tôi đang thử nghiệm nó dưới dạng dữ liệu trực tiếp:
@Captor
lateinit var captor: ArgumentCaptor<State<UserWallets>>
@Mock
lateinit var walletsObserver: Observer<State<UserWallets>>
@Test
fun `observe user wallets ok`() = runBlockingTest {
viewModel.userWallet.asLiveData().observeForever(walletsObserver)
viewModel.getUserWallets()
captor.run {
Mockito.verify(walletsObserver, Mockito.times(3)).onChanged(capture())
Assertions.assertThat(allValues[0] is State.Init).isTrue()
Assertions.assertThat(allValues[1] is State.Loading).isTrue()
Assertions.assertThat(allValues[2] is State.Success).isTrue()
}
}
runBlockingTestchỉ bỏ qua sự chậm trễ trong trường hợp của bạn nhưng không ghi đè người điều phối được sử dụng trong ViewModel bằng người điều phối thử nghiệm của bạn. Bạn cần phải đưa TestCoroutineDispatchervào ViewModel của mình hoặc vì bạn đang sử dụng viewModelScope.launch {}mà đã sử dụng Dispatchers.Maintheo mặc định, bạn cần ghi đè người điều phối chính qua Dispatchers.setMain(testCoroutineDispatcher). Bạn có thể tạo và thêm quy tắc sau vào tệp thử nghiệm của mình.
class MainCoroutineRule(
val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()
) : TestWatcher() {
override fun starting(description: Description?) {
super.starting(description)
Dispatchers.setMain(testDispatcher)
}
override fun finished(description: Description?) {
super.finished(description)
Dispatchers.resetMain()
testDispatcher.cleanupTestCoroutines()
}
}
Và trong tệp thử nghiệm của bạn
@get:Rule
var mainCoroutineRule = MainCoroutineRule()
@Test
fun `observe user wallets ok`() = mainCoroutineRule.testDispatcher.runBlockingTest {
}
Btw nó luôn luôn là một thực hành tốt để tiêm điều phối viên. Ví dụ: nếu bạn đang sử dụng một điều phối viên khác với Dispatchers.Mainphạm vi quy trình đăng ký viewModelScope.launch(Dispatchers.Default)của bạn, thì bài kiểm tra của bạn sẽ lại thất bại ngay cả khi bạn đang sử dụng một điều phối viên kiểm tra. Lý do là bạn chỉ có thể ghi đè điều phối viên chính Dispatchers.setMain()vì nó có thể được hiểu từ tên của nó nhưng không Dispatchers.IOhoặc Dispatchers.Default. Trong trường hợp đó, bạn cần phải đưa mainCoroutineRule.testDispatchervào mô hình chế độ xem của mình và sử dụng trình điều phối được tiêm vào thay vì mã hóa cứng nó.
Jana Duggar đã cởi mở về việc tìm kiếm tình yêu của mình. Đây là tất cả những gì cô ấy nói về chủ đề này và khoảng thời gian 5 năm kết hôn của cô ấy.
Ngôi sao của 'Outlander' Sam Heu Afghanistan gần đây đã tiết lộ những gì anh ấy sẽ làm từ phim trường để tưởng nhớ Jamie Fraser, vai diễn đã đưa anh ấy trở thành một ngôi sao.
"She Loves You" được viết trong một giờ, thu âm trong một ngày và là bài hát của The Beatles với một trong những màn trình diễn xuất sắc nhất trong sự nghiệp của họ.
Dolly Parton và bà Bessie của cô ấy có một mối quan hệ đặc biệt. Bà Parton ốm nặng, nhưng điều đó không ngăn được Dolly chơi khăm bà.
Bạn có thể nghĩ rằng gỗ sồi hoặc gỗ hồ đào rất cứng, nhưng khi nói đến loại gỗ cứng nhất thế giới thì chúng thậm chí còn không có loại nào sánh bằng.
Đại dương tràn ngập vẻ đẹp, nhưng cũng ẩn chứa một số sinh vật biển đáng sợ nhất hành tinh. Nhiều loài trong số này ẩn núp sâu dưới bề mặt đại dương, trong thế giới tối tăm, áp suất cao của biển sâu.
Nếu bạn đang chiến đấu với quái vật hung hãn hoặc chuẩn bị cho các tình huống PvP, việc nắm rõ những phép thuật kiếm tốt nhất trong Minecraft có thể mang lại cho bạn lợi thế lớn. Phép thuật kiếm cho phép bạn gây nhiều sát thương hơn, tăng lượng quái vật rơi ra và kéo dài độ bền của kiếm.
Khi nói đến các nước xã hội chủ nghĩa, người ta thường hình dung ra sự kiểm soát hoàn toàn của chính phủ và không có sở hữu tư nhân. Nhưng trên thực tế, các nền kinh tế xã hội chủ nghĩa rất khác nhau.
“Những đứa trẻ” tung dàn khách mời tên tuổi và nhiều tin tức chấn động
Chiếc RAV4 này được khẳng định là ở tình trạng tuyệt vời và được chuẩn bị cho một trò chơi ghế âm nhạc.
Cảnh quay từ máy bay không người lái đã ghi lại cảnh lính cứu hỏa dường như đang cố gắng dập tắt ngọn lửa.
Eyes of Wakanda liên kết trực tiếp với MCU, cùng với các cập nhật về X-Men '97, What If..., Daredevil, v.v.
Marilyn Monroe đã mặc một chiếc váy trắng nổi tiếng trong bộ phim 'The Seven Year Itch'. Sau đây là mọi thông tin cần biết về chiếc váy và khoảnh khắc mang tính biểu tượng của Monroe trên song sắt tàu điện ngầm.
John Cleese kết hôn với vợ mình, Jennifer Wade, vào năm 2012. Sau đây là mọi thông tin cần biết về vợ của John Cleese, Jennifer Wade.
Patton Oswalt kết hôn với vợ mình, nữ diễn viên Meredith Salenger, vào năm 2017. Sau đây là mọi thông tin cần biết về vợ của Patton Oswalt, Meredith Salenger.
Michael C. Hall đã kết hôn với vợ Morgan Macgregor từ năm 2016. Dưới đây là tất cả những điều cần biết về vợ của Michael C. Hall.
Nó đập vào mắt tôi Đột ngột như nó thường xảy ra Nó lại ở giữa chừng <Không, không phải cái ở Thái Bình Dương đâu bạn màu hạt dẻ, cái ở lễ hội hóa trang> Mọi tiêu đề đều ầm ĩ…..
Vào năm 2022, với việc phát hành GPT-3, kỹ năng viết dường như trở nên ít quan trọng hơn. Với AI, những người viết kém cũng có thể tạo ra đội ngũ nhân viên chất lượng.
Trong thế giới có nhịp độ nhanh và cạnh tranh ngày nay, sự nghiệp của một người đóng một vai trò quan trọng trong sự phát triển cá nhân, ổn định tài chính và sự hài lòng trong cuộc sống nói chung. Tuy nhiên, nhiều cá nhân thấy mình bị mắc kẹt trong một chu kỳ trì trệ và không hài lòng không ngừng, dần dần lãng phí trong cuộc sống nghề nghiệp của họ.
Tuần trước, tôi nhận thấy một thông cáo báo chí, được gửi qua PressGazette (một trang web tin tức truyền thông của Anh). Bài báo thông báo rằng Acast, công ty quảng cáo và lưu trữ podcast của Scandi, sẽ lãnh đạo một tập đoàn gồm các nhà xuất bản “có lẽ là có ảnh hưởng nhất” trong lĩnh vực podcasting.