Ошибка насмешки Класс, который содержит ссылку на SQLiteOpenHelper
Я пишу модульный тест для моего докладчика, который необходим для проверки моего локального источника данных.
Вот мой простой тест:
public class AddressPresenterTest {
@Mock
private AddressView mView;
@Mock
private AddressDataSource mDataSource;
@Mock
private AddressLocalDataSource mLocalDataSource;
@Captor
ArgumentCaptor<DataSourceCallback<Province>> mProvinceCallbackCaptor;
private AddressPresenter mPresenter;
@Before
public void beforeTest() {
MockitoAnnotations.initMocks(this);
mPresenter = new AddressPresenter(mDataSource, mView);
mPresenter.setLocalDataSource(mLocalDataSource);
}
@Test
public void When_SelectProvince_DataIsNull_ShowErrorMessage() {
mPresenter.getLocalProvinceById(2129023);
// Cause data source has callback, we need to capture the callback
ArgumentCaptor<Integer> provinceIdCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mLocalDataSource).fetchProvinceById(provinceIdCaptor.capture(), mProvinceCallbackCaptor.capture());
mProvinceCallbackCaptor.getValue().onFailedLoad();
verify(mView).loadContentError();
}
}
Когда я запускаю этот тест, я получил ошибку,
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class com.dai.uangteman.data.AddressLocalDataSource.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
Java : 1.8
JVM vendor name : Oracle Corporation
JVM vendor version : 25.77-b03
JVM name : Java HotSpot(TM) 64-Bit Server VM
JVM version : 1.8.0_77-b03
JVM info : mixed mode
OS name : Mac OS X
OS version : 10.12.6
Underlying exception : java.lang.IllegalArgumentException: Could not create type
at com.dai.uangteman.view.fragment.presenter.AddressPresenterTest.beforeTest(AddressPresenterTest.java:41)
...
Caused by: java.lang.IllegalArgumentException: Could not create type
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:140)
... 28 more
Caused by: java.lang.NoClassDefFoundError: android/database/sqlite/SQLiteOpenHelper
at java.lang.ClassLoader.defineClass1(Native Method)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:138)
... 45 more
Caused by: java.lang.ClassNotFoundException: android.database.sqlite.SQLiteOpenHelper
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
... 87 more
Когда я обойти, чтобы изменить свой AddressLocalDataSource
класс, я нашел что-то странное.
public class AddressLocalDataSource {
private StaticDatabaseHelper mDatabaseHelper;
// /**
// * @param mDatabaseHelper
// */
// public AddressLocalDataSource(StaticDatabaseHelper mDatabaseHelper) {
// this.mDatabaseHelper = mDatabaseHelper;
// }
public void setDatabaseHelper(StaticDatabaseHelper mDatabaseHelper) {
this.mDatabaseHelper = mDatabaseHelper;
}
...
}
Ниже того, что я нашел:
- Я пытаюсь удалить мой конструктор и метод установки, который содержит
StaticDatabaseHelper
параметр объекта и все работает! - Я пытаюсь изменить
StaticDatabaseHelper
инициализация в методе установки это не работает!
Проблема моя AddressLocalDataSource
нужен экземпляр StaticDatabaseHelper
учебный класс.
Любая идея? благодарю вас
2 ответа
✔ Ответить
Через пару часов я ищу решение и получаю самое простое решение. Я думаю, что есть некоторые неполные в библиотеке Android для тестирования. Поэтому я просто запускаю команду gradle для очистки:
./gradlew clean test
И это работает сейчас, я просто издеваюсь StaticDatabaseHelper
класс в этом случае. Итак, это мой последний тестовый класс:
public class AddressPresenterTest {
@Mock
private AddressView mView;
@Mock
private AddressDataSource mDataSource;
@Mock
private AddressLocalDataSource mLocalDataSource;
@Captor
ArgumentCaptor<DataSourceCallback<Province>> mProvinceCallbackCaptor;
private AddressPresenter mPresenter;
@Before
public void beforeTest() throws Exception {
MockitoAnnotations.initMocks(this);
mPresenter = new AddressPresenter(mDataSource, mView);
mPresenter.setLocalDataSource(mLocalDataSource);
}
@Test
public void When_SelectProvince_DataIsNull_ShowErrorMessage() {
mPresenter.getLocalProvinceById(2129023);
// Cause data source has callback, we need to capture the callback
ArgumentCaptor<Integer> provinceIdCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mLocalDataSource).fetchProvinceById(provinceIdCaptor.capture(), mProvinceCallbackCaptor.capture());
mProvinceCallbackCaptor.getValue().onFailedLoad();
verify(mView).loadContentError();
}
}
Надеюсь, это поможет, спасибо
Кажется, вам также нужно смоделировать StaticDatabaseHelper. Затем Mockito должен автоматически вставить ваш смоделированный экземпляр в AddressLocalDataSource. Поэтому добавление следующей строки может решить вашу проблему:
public class AddressPresenterTest {
@Mock
StaticDatabaseHelper mockedDatabaseHelper;
...
В моем случае в моем проекте используется javassist-3.11.0.GA.jar. После того, как Google опубликовал некоторые статьи о вышеупомянутой проблеме, связанной с версией javassist, я пытаюсь обновить javassist до javassist-3.18.2-GA.jar или javassist-3.21.0-GA.jar, проблема решена.
Некоторые другие проблемы могут быть решены следующим образом:
java.lang.VerifyError: Несогласованные кадры стека в целевой ветви 40 Исключение
,
java.lang.RuntimeException: java.io.IOException: недопустимый тип константы: 18
,
Основное исключение: java.lang.IllegalArgumentException: не удалось создать тип
С Уважением,