java - doNothing.When for private void 方法本身正在调用方法

标签 java mockito powermockito

我正在尝试测试我的一个名为 Store 的类,特别是一个名为removeFromFavourite 的方法 下面是方法

    public void removeFromFavourite(Quote quote) {
        if(quote == null) {
            throw new IllegalArgumentException("Quote can't be null");
        }
        if (quote.getId() <1) {
            throw new IllegalArgumentException("Quote id can't be less than 1");
        }
        realm.beginTransaction();
        QuoteRealMObject object = realm.where(QuoteRealMObject.class).
                equalTo(QuoteRealMObject.ID, quote.getId()).findFirst();
        if(object != null) {
            deleteObject(object);
        }
        realm.commitTransaction();
    }


    private void deleteObject(RealmObject object) {
        object.deleteFromRealm();
    }

我创建了deleteObject方法来调用deleteFromRealm,因为deleteFromRealm是最终的,因此我无法模拟它。

我的期望是通过创建其 spy 来模拟调用“deleteObject”ob Store 的对象

这是我的@Before方法

private Realm mockedRealm;
private Store store;

@Before
public void setUp() throws Exception {
    mockedRealm = Mockito.mock(Realm.class);
    store = new Store(mockedRealm);
    store = PowerMockito.spy(store);
}

因此,我创建了 Realm 的模拟对象,并使用它来创建 Store 类的对象,然后从 store 的对象中创建了一个 spy ,并将其分配回 store 对象本身。

下面是removeFromFavourite的测试方法

@Test
    public void removeFromFavourite() throws Exception {
        Quote quot = new Quote();
        quot.setId(1);
        RealmQuery<QuoteRealMObject> query = Mockito.mock(RealmQuery.class);
        RealmQuery<QuoteRealMObject> filteredQuery = Mockito.mock(RealmQuery.class);
        Mockito.when(mockedRealm.where(QuoteRealMObject.class)).thenReturn(query);
        Mockito.when(query.equalTo(QuoteRealMObject.ID, 1)).thenReturn(filteredQuery);
        QuoteRealMObject mockedObject = Mockito.mock(QuoteRealMObject.class);
        Mockito.when(filteredQuery.findFirst()).thenReturn(mockedObject);
        PowerMockito.doNothing().when(store, "deleteObject", mockedObject);            
        store.removeFromFavourite(quot);
    }

这里的行 PowerMockito.doNothing().when(store, "deleteObject", mockedObject); 本身正在调用真正的私有(private)方法“deleteObject” 我收到了未完成的模拟异常

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at com.kgcorner.vachan.io.StoreTest.removeFromFavourite(StoreTest.java:132)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, which is not supported
 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed


    at org.mockito.internal.runners.DefaultInternalRunner$1$1.testFinished(DefaultInternalRunner.java:70)
    at org.junit.runner.notification.SynchronizedRunListener.testFinished(SynchronizedRunListener.java:56)
    at org.junit.runner.notification.RunNotifier$7.notifyListener(RunNotifier.java:190)
    at org.junit.runner.notification.RunNotifier$SafeNotifier.run(RunNotifier.java:72)
    at org.junit.runner.notification.RunNotifier.fireTestFinished(RunNotifier.java:187)
    at org.junit.internal.runners.model.EachTestNotifier.fireTestFinished(EachTestNotifier.java:38)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:331)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    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.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    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.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

知道我哪里错了吗?

最佳答案

我认为 when 中的第三个参数应该是一个模拟匹配器:

PowerMockito.doNothing().when(store, "deleteObject", eq(mockedObject));

关于java - doNothing.When for private void 方法本身正在调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55913409/

相关文章:

java - 我可以使用 doReturn 与 PowerMockito 链接返回吗?

java - 将 Mockito 模拟注入(inject)到通过工厂方法返回的 bean 中

java - 模拟子类对象和父类(super class)引用

unit-testing - 使用mockito模拟GWT EventBus

java - @Spy 在两个列表上注释时不起作用

mocking - 模拟静态函数调用时出错

java - android服务检测主屏幕是否打开

java - 为什么这个静态内部类不能在其外部类上调用非静态方法?

java - Gson 反序列化为 Map 通用类型

java - java.lang.NoClassDefFoundError:javax/security/auth/kerberos/KeyTab