繁体   English   中英

如何验证调用是在我的方法中的特定列表上进行的?

[英]How do I verify a call is made on a specific list in my method?

如果我有以下代码:

public void process(List<String> messages){
    
    Map<String, List<String>> mapofLists = new HashMap<>();
    List<String> list1 = new ArrayList();
    List<String> list2 = new ArrayList();
    List<String> list3 = new ArrayList();    

    for (String message : messages) {
        if(message.contains("123")){
            list.add(message);
        }
        else if(message.contains("456")) {
            list2.add(message);
        }
        else {
            list3.add(message);
        }
    }

    mapofLists.put("123",list1);
    mapofLists.put("345",list2);
    mapofLists.put("678",list3);

    service.makeApiCall(mapofLists);

}

我知道如何在最后验证 api 调用。 但是我对如何编写测试以确保每个列表(list1、list2、list3)根据传入的消息列表添加了正确数量的消息感到困惑。我该怎么做?

据我所知,Mockito 不允许您公开和模拟这样的方法的内部结构。 如果您将mapOfLists或单个列表传递给process方法,您将能够使用与验证对服务方法的调用相同或相似的方法相当容易地做到这一点; 但是,对于这种方法没有多大意义,因为用户需要事先创建每个值,并且如果您决定更改所需的列表数量,那将很麻烦。

可能最好的方法是将 api 调用移出process方法,并返回mapOfLists稍后使用服务发送。 您可以在 map 上使用各种断言来确保发送正确的数据。

这也将允许您将这两个操作解耦,以便处理和发送真正成为 2 个独立的操作,而不是 1 个,从而使您的代码更易于维护和阅读。

public class Processor {
    public static Map<String, List<String>> processor(List<String> message) {
        Map<String, List<String>> mapOfLists = new HashMap<>();

        List<String> list1 = new ArrayList();
        List<String> list2 = new ArrayList();
        List<String> list3 = new ArrayList();    

        for (String message : messages) {
            if(message.contains("123")) {
                list.add(message);
            } else if(message.contains("456")) {
                list2.add(message);
            } else {
                list3.add(message);
            }
        }

        mapOfLists.put("123",list1);
        mapOfLists.put("345",list2);
        mapOfLists.put("678",list3);

        return mapOfLists;
    }
}

并在您的测试文件中

public class TestProcessing {
    @Test
    public void testEmpty() {
        List<String> messages = new ArrayList<>();

        Map<String, List<String>> expected = new HashMap<>();
        expected.put("123", new ArrayList<>();
        expected.put("345", new ArrayList<>();
        expected.put("678", new ArrayList<>();

        assertEquals(Processor.process(messages), expected);
    }
}

您可以使用ArgumentCaptor拦截 API 调用的参数,然后根据需要验证列表中适当数量的消息和/或 map 的全部内容、其键集和值。

示例测试可能如下所示(未测试):

@Mock
ApiService service; // mock makeApiCall

@InjectMocks
ProcessService processService; // implements process(List<String messages>)

@Test
void processOk() {
    ArgumentCaptor<Map<String, List<String>>> captor = ArgumentCaptor.forClass(Map.class);

    doNothing().when(service).makeApiCall(any());

    processService.process(List.of("123", "456_1", "456_2", "Test"));
    verify(service, times(1)).makeApiCall(captor.capture());

    Map<String, List<String>> map = captor.getValue();
    
    assertEquals(3, map.size());
    assertEquals(1, map.get("123"));
    assertEquals(2, map.get("345"));
    assertEquals(1, map.get("678"));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM