我正在为ViewModel / StateMachine编写UnitTest(使用MVI模式)。 ViewModel内部注入了API bean(由Retrofit构建)
class UserViewModel(
private val API: API
)
object UserModule {
fun get(): Module {
return module {
viewModel { UserViewModel(api = get()) }
}
}
}
object NetworkModule {
fun get(): Module {
return module {
... // various retrofit Beans
single{ Api(retrofit = get()) }
}
}
}
这在我的应用程序中有效,但是当进行单元测试时,我要对来自API
的响应进行存根,在一个测试中对它的错误进行存根,在另一个测试中对它的模拟响应进行存根,因此将一些MockNetworkModule,MockFailingNetworkModule
与相同的接口似乎是一个过大的选择,而不是像在测试代码块中准备好模拟数据那样迅速进行。
这是我尝试对呼叫进行存根的方法,但它仍然使用旧的实现并进行网络呼叫
class UserTest : KoinTest {
@get:Rule
val schedulers = RxImmediateSchedulerRule()
private val viewModel: UserViewModel by inject()
@Before
fun before() {
startKoin {
modules(
listOf(
UserModule.get(),NetworkModule.get()
)
)
}
}
@After
fun after() {
stopKoin()
}
}
我的测试是这样写的(类似于我从Koin文档中读到的内容):
@Test
fun `user test passing`() {
val mockUserData = UserData("name","surname")
declareMock<Api> {
given(this.getUserData()).willReturn { Single.just(mockUserData) }
}
viewModel.refresh() // calls api.getUserData() inside
... expecting mockUserData but getting real api call
}
@Test
fun `user test failing`() {
declareMock<Api> {
given(this.getUserData()).willReturn { Single.error(Exception("mock")) }
}
viewModel.refresh() // calls api.getUserData() inside
... expecting exception but getting real api call
}
我也尝试过declareMock<UserViewModel>{ given(this.api.getUserData()} ...
,但在NullPointerException
上有this.api
。
TL; DR 如何正确地将已经注入的bean存入viewModel中以进行即时的单元测试