使用RealmResults时,为什么我的Robolectric测试失败了?

时间:2017-03-01 12:38:28

标签: java android mockito realm robolectric

我在我的项目中使用了Realm,并且正在尝试让测试正常运行。我已经完成了测试通过的所有事情,直到你开始使用RealmResults从数据库中取出东西。下面的代码是我获得结果的方式

private void getUser(){
    realm.beginTransaction();
    RealmResults<User> realmUsers = realm.where(User.class).findAll();
    user = realmUsers.first();
    realm.commitTransaction();
    Log.d("Test", user.getFirstName() + " " + user.getLastName());
}

只需返回存储在Realm中的所有结果。下面是对完整单元测试的测试。

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP, manifest = "src/main/AndroidManifest.xml")
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
@PrepareForTest({Realm.class, RealmConfiguration.class,
        RealmQuery.class, RealmResults.class, RealmCore.class, RealmResults.class})
public class SecondActivityTest {

    @Rule
    public PowerMockRule rule = new PowerMockRule();

    private SecondActivity activity;

    private RealmResults<User> realmUsers;

    @Before
    public void setUp(){
    MockitoAnnotations.initMocks(this);

    // Setup Realm + Mock
    mockStatic(Realm.class);
    mockStatic(RealmConfiguration.class);
    mockStatic(RealmCore.class);
    mockStatic(RealmQuery.class);

    final Realm mockRealm = mock(Realm.class);
    doNothing().when(RealmCore.class);
    RealmCore.loadLibrary(any(Context.class));

    when(Realm.getDefaultInstance()).thenReturn(mockRealm);
    when(mockRealm.createObject(User.class)).thenReturn(new User());

    User userOne = new User("Matt", "Dunn");
    User userTwo = new User("Michael", "Stoddart");

    List<User> userList = Arrays.asList(userOne, userTwo);

    RealmQuery<User> realmQuery = mockRealmQuery();
    RealmResults<User> mockResults = mockRealmResults();

    when(mockResults.iterator()).thenReturn(userList.iterator());
    when(mockResults.size()).thenReturn(userList.size());

    when(mockResults.first()).thenReturn(userList.get(0));

    activity = Robolectric.setupActivity(SecondActivity.class);
}

    @Test
    public void checkActivityNotNull(){
        Assert.assertNotNull(activity);   
    }

    @SuppressWarnings("unchecked")
    private <T extends RealmObject> RealmQuery<T> mockRealmQuery() {
        return mock(RealmQuery.class);
    }

    @SuppressWarnings("unchecked")
    private <T extends RealmObject> RealmResults<T> mockRealmResults() {
        return mock(RealmResults.class);
    }
}

然而,即使我已经遵循了领域提供的指南,这仍然会引发以下异常

https://github.com/realm/realm-java/blob/master/examples/unitTestExample/src/test/java/io/realm/examples/unittesting/ExampleActivityTest.java

Method threw 'org.mockito.exceptions.misusing.NotAMockException' exception. Cannot evaluate io.realm.Realm$$EnhancerByMockitoWithCGLIB$$61d46d71.toString()

我是否错误地嘲笑RealmResults?或者是完全独立的东西?

编辑:

测试失败时提供的完整堆栈跟踪是

java.lang.NullPointerException
    at com.example.mathewdunn.realmtest.activity.SecondActivity.getUser(SecondActivity.java:34)
    at com.example.mathewdunn.realmtest.activity.SecondActivity.onCreate(SecondActivity.java:29)
    at android.app.Activity.performCreate(Activity.java:5933)
    at org.robolectric.util.ReflectionHelpers.callInstanceMethod(ReflectionHelpers.java:195)
    at org.robolectric.util.ActivityController$1.run(ActivityController.java:122)
    at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:304)
    at org.robolectric.shadows.CoreShadowsAdapter$2.runPaused(CoreShadowsAdapter.java:45)
    at org.robolectric.util.ActivityController.create(ActivityController.java:118)
    at org.robolectric.util.ActivityController.create(ActivityController.java:129)
    at org.robolectric.util.ActivityController.setup(ActivityController.java:210)
    at org.robolectric.Robolectric.setupActivity(Robolectric.java:46)
    at com.example.mathewdunn.realmtest.SecondActivityTest.setUp(SecondActivityTest.java:83)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.powermock.modules.junit4.rule.PowerMockStatement$1.run(PowerMockRule.java:83)
    at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1899)
    at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:801)
    at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:666)
    at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401)
    at org.powermock.classloading.AbstractClassloaderExecutor.getResult(AbstractClassloaderExecutor.java:69)
    at org.powermock.classloading.AbstractClassloaderExecutor.executeWithClassLoader(AbstractClassloaderExecutor.java:59)
    at org.powermock.classloading.SingleClassloaderExecutor.execute(SingleClassloaderExecutor.java:67)
    at org.powermock.classloading.AbstractClassloaderExecutor.execute(AbstractClassloaderExecutor.java:43)
    at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:75)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

调试测试时,我收到了NotAMock异常。

修改编辑:

在进行一些更改之后,现在正在抛出另一个异常。

com.thoughtworks.xstream.converters.ConversionException: Cannot convert type org.apache.tools.ant.Project to type org.apache.tools.ant.Project
---- Debugging information ----
message             : Cannot convert type org.apache.tools.ant.Project to type org.apache.tools.ant.Project
class               : org.apache.tools.ant.Project$1
required-type       : org.apache.tools.ant.Project$1
converter-type      : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path                : /org.powermock.modules.junit4.rule.PowerMockStatement$1/outer-class/fNext/next/outer-class/outer-class/dependencyResolver/dependencyResolver/project/isLoggingMessage/outer-class
line number         : 230
class[1]            : org.apache.tools.ant.Project
class[2]            : org.robolectric.internal.dependency.MavenDependencyResolver
class[3]            : org.robolectric.internal.dependency.CachedDependencyResolver
class[4]            : org.robolectric.RobolectricGradleTestRunner
class[5]            : org.robolectric.RobolectricTestRunner$HelperTestRunner
class[6]            : org.robolectric.RobolectricTestRunner$HelperTestRunner$1
class[7]            : org.junit.internal.runners.statements.RunBefores
class[8]            : org.powermock.modules.junit4.rule.PowerMockStatement
class[9]            : org.powermock.modules.junit4.rule.PowerMockStatement$1
version             : not available
-------------------------------

    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:456)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:503)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:429)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:503)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:429)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:503)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:429)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:503)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:429)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:503)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:429)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:503)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:429)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:503)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:429)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:503)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:429)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:503)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:429)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1230)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1214)
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1085)
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1076)
    at org.powermock.classloading.DeepCloner.clone(DeepCloner.java:55)
    at org.powermock.classloading.AbstractClassloaderExecutor.executeWithClassLoader(AbstractClassloaderExecutor.java:56)
    at org.powermock.classloading.SingleClassloaderExecutor.execute(SingleClassloaderExecutor.java:67)
    at org.powermock.classloading.AbstractClassloaderExecutor.execute(AbstractClassloaderExecutor.java:43)
    at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:75)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:265)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:191)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:56)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:157)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

干杯

1 个答案:

答案 0 :(得分:4)

不完整的模拟

您错过了Realm test example

中的这些行
    // The for(...) loop in Java needs an iterator, so we're giving it one that has items,
    // since the mock RealmResults does not provide an implementation. Therefore, anytime
    // anyone asks for the RealmResults Iterator, give them a functioning iterator from the
    // ArrayList of Persons we created above. This will allow the loop to execute.
    when(people.iterator()).thenReturn(personList.iterator());

    // Return the size of the mock list.
    when(people.size()).thenReturn(personList.size());

解释在代码注释中 - 基本上RealmResults就像一个Realm'Colrsor'并且本身不包含任何数据,但是作为存储在Realm中的对象的代理。

考虑到这一点,以及模拟实例没有任何迭代器的事实,很明显,您必须将此RealmResults上的迭代重定向到另一个功能齐全的List实例 - 在您的情况下userList

    when(mockResults.iterator()).thenReturn(userList.iterator());
    when(mockResults.size()).thenReturn(userList.size());

这将允许您迭代并获取模拟的RealmResults实例的大小。

由于您在first()方法中对RealmResults进行了getUser()调用,因此您还需要模拟此方法:

    when(mockResults.first()).thenReturn(userList.get(0));

另请注意,realm.beginTransaction()方法中对realm.commitTransaction()getUser()的调用是多余的,因为您没有执行任何写操作。您可以安全地删除它们,也可以模仿它们:

    doCallRealMethod().when(mockRealm).beginTransaction();
    doCallRealMethod().when(mockRealm).commitTransaction();