如何解决无法实例化名为“viewModel”、类型为“class com.example.digiandroidapp.viewmodel.CarViewModel”的@InjectMocks 字段?
我正在开发 android 应用程序,我已经在 android 的 viewmodel 类中实现了 mockito,但是当我运行测试时,我遇到了以下异常
org.mockito.exceptions.misusing.InjectMocksException:
Cannot instantiate @InjectMocks field named 'viewmodel' of type 'class com.example.digiandroidapp.viewmodel.Carviewmodel'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : Parameter specified as non-null is null: method com.example.digiandroidapp.viewmodel.Carviewmodel.<init>,parameter carsInfoDao
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:61)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:61)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: java.lang.NullPointerException: Parameter specified as non-null is null: method com.example.digiandroidapp.viewmodel.Carviewmodel.<init>,parameter carsInfoDao
at com.example.digiandroidapp.viewmodel.Carviewmodel.<init>(Carviewmodel.kt)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.mockito.internal.util.reflection.ReflectionMemberAccessor.lambda$newInstance$0(ReflectionMemberAccessor.java:29)
at org.mockito.internal.util.reflection.ReflectionMemberAccessor.newInstance(ReflectionMemberAccessor.java:29)
at org.mockito.internal.util.reflection.ReflectionMemberAccessor.newInstance(ReflectionMemberAccessor.java:20)
at org.mockito.internal.util.reflection.FieldInitializer$ParameterizedConstructorInstantiator.instantiate(FieldInitializer.java:287)
at org.mockito.internal.util.reflection.FieldInitializer.acquireFieldInstance(FieldInitializer.java:146)
at org.mockito.internal.util.reflection.FieldInitializer.initialize(FieldInitializer.java:91)
at org.mockito.internal.configuration.injection.ConstructorInjection.processInjection(ConstructorInjection.java:48)
at org.mockito.internal.configuration.injection.MockInjectionStrategy.process(MockInjectionStrategy.java:68)
at org.mockito.internal.configuration.injection.MockInjectionStrategy.relayProcesstoNextStrategy(MockInjectionStrategy.java:91)
at org.mockito.internal.configuration.injection.MockInjectionStrategy.process(MockInjectionStrategy.java:71)
at org.mockito.internal.configuration.injection.MockInjection$OngoingMockInjection.apply(MockInjection.java:88)
at org.mockito.internal.configuration.DefaultInjectionEngine.injectMocksOnFields(DefaultInjectionEngine.java:26)
at org.mockito.internal.configuration.InjectingAnnotationEngine.injectCloseableMocks(InjectingAnnotationEngine.java:119)
at org.mockito.internal.configuration.InjectingAnnotationEngine.processInjectMocks(InjectingAnnotationEngine.java:62)
at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:49)
at org.mockito.MockitoAnnotations.openMocks(MockitoAnnotations.java:82)
at org.mockito.internal.framework.DefaultMockitoSession.<init>(DefaultMockitoSession.java:43)
at org.mockito.internal.session.DefaultMockitoSessionBuilder.startMocking(DefaultMockitoSessionBuilder.java:83)
at org.mockito.internal.junit.JUnitSessionStore$1.evaluate(JUnitSessionStore.java:38)
在我的 Carviewmodel.kt 下面
class Carviewmodel(
private val api: ApiInterface,private val carsInfoDao: CarsInfoDao,private val carsLocationDao: CarsLocationDao,) : viewmodel() {
private val _cars = mutablelivedata<List<CarInfo>>()
val cars: LiveData<List<CarInfo>> = _cars
private val _error = SingleLiveEvent<Exception>()
val error: LiveData<Exception> = _error
private val _loading = mutablelivedata<Boolean>()
val loading: LiveData<Boolean> = _loading
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun getAllCars() {
viewmodelScope.launch {
try {
val result = api.getAllCars()
println("dataaaa -> $result")
_loading.value = true
_cars.value = result
val carsInfoList = mutablelistof<CarsInfoEntity>()
val carsLocationList = mutablelistof<CarsLocationEntity>()
result.forEach { carsInfo: CarInfo ->
carsInfoList.add(
CarsInfoEntity(
carsInfo.id,carsInfo.brand,carsInfo.model,carsInfo.imageURL,carsInfo.fuel,carsInfo.pricePerDay,carsInfo.currency,carsInfo.year,carsInfo.type,carsInfo.status,carsInfo.groupId,carsInfo.registrationPlate,carsInfo.createdAt,carsInfo.updatedAt,carsInfo.subjectTypeId
)
)
carsLocationList.add(
CarsLocationEntity(
carsInfo.id,carsInfo.location.latitude,carsInfo.location.longitude,)
)
}
carsInfoDao.insertCarsInfo(carsInfoList)
carsLocationDao.insertCarsLocation(carsLocationList)
} catch (e: Exception) {
_error.value = e
} finally {
_loading.value = false
}
}
}
}
低于 viewmodelTest
class CarviewmodelTest {
@get:Rule
val mockitoRule: MockitoRule = MockitoJUnit.rule()
@get:Rule
var mainCoroutineRule = MainCoroutineRule()
@get:Rule
val instantTaskExecutorRule = InstantTaskExecutorRule()
@InjectMocks
private lateinit var viewmodel: Carviewmodel
@Mock
private lateinit var api: ApiInterface
@Mock
private lateinit var cars: List<CarInfo>
private val testdispatcher = TestCoroutinedispatcher()
@Before
fun setup() {
dispatchers.setMain(testdispatcher)
}
@After
fun tearDown() {
dispatchers.resetMain()
testdispatcher.cleanupTestCoroutines()
}
@Test
fun `get cars positive case`() {
val cardData = cars
observe(viewmodel.cars)
wheneverBlocking { api.getAllCars() }.thenReturn(cardData)
viewmodel.getAllCars()
assert(viewmodel.cars.value == cardData)
}
@Test
fun `get cars negative case`() {
val userObserver = observe(viewmodel.cars)
val errorObserver = observe(viewmodel.error)
val exception = IOException("404")
wheneverBlocking { api.getAllCars() }.thenThrow(exception)
viewmodel.getAllCars()
assert(viewmodel.error.value == exception)
verifyZeroInteractions(userObserver)
verify(errorObserver).onChanged(exception)
}
}
我想知道是什么导致了问题我必须做什么才能避免出现异常我已经关注了很多stackoverflow帖子它没有解决我的问题
解决方法
我通过在设置方法中添加 MockitoAnnotations.initMocks(this) 来修复
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。