当前位置: 首页 > 面试题库 >

错误模拟类,其中包含对SQLiteOpenHelper的引用

堵乐
2023-03-14
问题内容

我为Presenter编写了单元测试,这需要模拟 本地数据源

这是我的简单测试:

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;
    }
    ...
}

下面我发现:

  1. 我尝试删除包含StaticDatabaseHelper对象参数的构造函数和setter方法,并且可以使用!
  2. 我尝试StaticDatabaseHelper在setter方法中更改初始化,但这种方法无效!

问题是我AddressLocalDataSource需要StaticDatabaseHelper类的实例。

任何想法?谢谢


问题答案:

✔答案

几个小时后,我正在寻找解决方案,我得到了最简单的解决方案。我认为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();
    }
}

希望有帮助,谢谢



 类似资料:
  • null 我看过其他几个类似的问题,但没有一个有帮助: 模拟包含对SQLiteOpenHelper引用的类时出错 使用mockito库在java中模拟最终类-我在导入PowerMock时遇到了很多问题 如何用mockito模拟最后一个类-我已经添加了依赖项,并用行创建了文件,正如答案中所建议的那样,我仍然得到同样的错误。我还尝试了建议的答案,但这给了我一个‘没有足够的信息来推断类型变量t'erro

  • 问题内容: 我有一个相当复杂的SQL查询,我敢肯定我无法使用ARel(Rails 3.0.10)完成 看看链接,但是它有一些联接和一个子句,而且我敢肯定对于ARel来说太复杂了。 但是我的问题是,在此查询如此复杂之前,我可以使用ARel添加其他模型来避免n + 1问题。现在,我正在使用find_by_sql,请不要使用。我仍然希望能够获取这些记录并将它们附加到我的模型实例上,但是确实不知道如何实现

  • 我是java编程语言的新手。我做了一个包名包。其中包含两个java类A. java和B. java。我用的是jdk1.5和tomcat。我想创建一个A类型的对象,并将其放在B. java中。下面是我如何试图做到这一点,但得到两个错误消息。 包装; A.java B.java Jdk1。5、tomcat和package pack位于下面的目录中 D:\java 下面是我编译A.java和B.java

  • 我有一个包含两个类的java包。A类和B类。我需要在B类中创建一个A类型的对象。我不知道发生了什么。请谁帮帮我。 包装; A类 B类 我用的是JDK1。5和tomcat,并将它们放在我的D驱动器的java文件夹中。 D:\java\jdk1。5. D:\java\tomcat 现在,我的包裹文件夹也在上面的位置 D:\java\pack 下面是我如何编译我的java类文件。 步骤1:编译A.jav

  • 问题内容: 对于单元测试,我需要模拟几个依赖项。依赖项之一是实现接口的类: 我需要设置一个此类的模拟对象,当提供一些指定参数时,该对象将返回一些指定值。 现在,我不确定的是,模拟接口或类是否更好 与 在测试方面有什么不同吗?首选的方法是什么? 问题答案: 在您的情况下,可能不会有太大的区别,但是首选的方法是模拟接口,就像通常情况下,如果您遵循TDD(测试驱动开发),那么即使在编写实现类之前,也可以

  • 当我启动模拟器时,我收到错误消息,因为 模拟器:PANIC:缺少“arm”CPU的模拟器引擎程序。 模拟器:进程已完成,退出代码为 1 Win 10 , Android Studio3.1.4 , AVD 联结 4 Api21