在 Android 单元测试中为 doNothing.when 子句接收 Mockito UnfinishedStubbingException

gre*_*qrl 0 android unit-testing mockito powermock rx-java

首先,我的设置是 RXJava 1、Retrofit 2,我使用的是 Java 7。

我有一个方法,当它被调用时,会将一个原子布尔值设置为 true。

然后该方法调用改造 API。

完成后,超时等......原子布尔值重置为false。

因此,我想测试一下,当我调用我的方法时,Atomic Boolean 设置为 true。

因此,我执行以下操作:

    assertFalse(orderUseCase.isOrderInProcess());

    orderUseCase.execute(id, orderWrapper, ts);

    assertTrue(orderUseCase.isOrderInProcess());
Run Code Online (Sandbox Code Playgroud)

测试布尔值是否为假。执行我的用例测试布尔值是否为真。

现在,为了执行最后一个测试,我需要确保 API 在调用时什么都不做(execute 方法将调用改造 API。

为了尝试什么都不做,我在测试用例的开头使用了以下行。

doNothing().when(orderAPI.orderComplete(anyString(), any(OrderWrapper.class)));
Run Code Online (Sandbox Code Playgroud)

但是,我收到以下错误:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at com.tfds.xms.unit_test.SingleTest.TestAtomicBooleanLocked(SingleTest.java:90)

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, you naughty developer!
 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
Run Code Online (Sandbox Code Playgroud)

从阅读其他人有类似问题的地方来看,答案表明他们的“何时”行正在调用另一个 Mock(我不相信我在做)或者他们没有完成我所拥有的“PrepareForTest”步骤完毕。但是,我想知道我的 prepareForTest 部分中的内容是否正确...

顺便说一句,我明白错误是指向我添加一个“thenReturn”,但这意味着 API“做”了一些事情,因此会导致 Atomic Boolean 再次解锁,这不是我想要的。

很感谢任何形式的帮助。

我的完整测试用例是:

@RunWith(TestRunner.class)
@PrepareForTest({OrderApiService.class, OrderUseCase.class})
public class SingleTest {

    @Rule
    public RxJavaResetRule pluginsReset = new RxJavaResetRule();

    private OrderApiService orderAPI;
    private OrderUseCase orderUseCase;
    private OrderRepository orderRepository;

    @Mock App app;

    @Before
    public void setUp() {

        orderAPI = mock(OrderApiService.class);

        orderRepository = new OrderRepository(app, orderAPI);

        orderUseCase = new OrderUseCase(orderRepository);

    }

    @Test
    public void TestAtomicBooleanLocked() throws Exception {

        doNothing().when(orderAPI.orderComplete(anyString(), any(OrderWrapper.class)));

        String id = "5";

        Order order = new Order();

        OrderWrapper orderWrapper = new orderWrapper(order);

        TestSubscriber<GenericResponse> ts = new TestSubscriber<GenericResponse>();

        assertFalse(orderUseCase.isOrderInProcess());

        orderUseCase.execute(id, orderWrapper, ts);

        assertTrue(orderUseCase.isOrderInProcess());

    }
}
Run Code Online (Sandbox Code Playgroud)

小智 6

doNothing()来自的方法Mockito与独立when()方法有点不同。只需将方法调用从.doNothing()这样的方式中推出来就可以了:

doNothing().when(orderAPI)
    .orderComplete(anyString(), any(OrderWrapper.class));
Run Code Online (Sandbox Code Playgroud)

测试愉快!