首页 > 解决方案 > “被通缉但未被调用;然而,还有其他与这个模拟“错误的交互

问题描述

单元测试不断给我=

Wanted but not invoked: However, there were exactly 3 interactions with this mock.

我要做的就是测试方法执行的超时时间 - 如果方法需要更多时间,则终止它并发布计数(以了解超时响应率)作为指标。

@Test
public void testTimeoutFunction() throws Exception {
    Response response = getResponseForTest();

    when(processor
            .process(any(Request.class)))
            .thenAnswer((Answer<Response>) invocation -> {
                Thread.sleep(100);
                return response;
            });

    when(itemRequest.getRequestContext()).thenReturn(itemRequestContext);

    testClass = spy(new TestClass(processor, executorService));
    List<Item> output = testClass.getItemList(ID, itemRequest);

    verify(testClass, times(1)).responseTimedOutCount();
    assertTrue(output.isEmpty());
    verify(testClass, timeout(EXECUTION_TIMEOUT)).buildResponse(itemRequest);
    verify(testClass, times(1)).buildResponse(itemRequest);
}

这是我正在测试的方法:

public class TestClass {

    @VisibleForTesting
    void  responseTimedOutCount() {
    //log metrics
    }

    private CompletableFuture<Response> getResponseAsync(final ScheduledExecutorService delayer,
                                                                             final ItemRequest itemRequest) {
        return timeoutWithTimeoutFunction(delayer, EXECUTION_TIMEOUT, TimeUnit.MILLISECONDS,
                CompletableFuture.supplyAsync(() -> getResponseWithTimeoutFunction(itemRequest), executorService),
                Response.emptyResponse(), () -> responseTimedOutCount());
    }


    private Response getResponseWithTimeoutFunction(final ItemRequest itemRequest) {
        //do something and return response
    }

    public List<Item> getItemList(final String id, final ItemRequest itemRequest) throws Exception {

        final ScheduledExecutorService delayer = Executors.newScheduledThreadPool(1);
        Response response;
        if(validateItemId(id){
            try {
                response = getResponseAsync(delayer, itemRequest).get();
            } catch (final Throwable t) {
                response = Response.emptyResponse();
            } finally {
                delayer.shutdown();
            }
            return transform(response, id).getItems(); 
        } else {
            return null;
        }
    }
}

Junit 的例外情况:

对于这个断言 -

verify(testClass, times(1)).responseTimedOutCount();

Wanted but not invoked:
testClass.responseTimedOutCount(); 

However, there were exactly 3 interactions with this mock:
testClass.getItemList(ID, itemRequest);
testClass.validateItemId(ID);
testClass.getResponseWithTimeoutFunction(itemRequest);

标签: javajunitmockitoassert

解决方案


推荐阅读