如何测试具有多个返回值的函数?

时间:2021-04-28 08:39:30

标签: java junit mockito

我目前正在学习 Java,并且正在制作一个电子商务网站。我目前正在编写一些测试。我的问题是我的控制器中的一个映射根据名为 results 的列表的长度返回不同的页面。这是一个搜索项目功能,如果该项目不存在,它会将您带回搜索项目页面,如果有一个具有该名称的项目,它会将您带到另一个页面,如果该项目有多个实例,它会返回您到第三页。映射如下。

@RequestMapping("/findItemByName")
    public String processFindForm(Item item, BindingResult result, Map<String, Object> model) {
        // allow parameterless GET request for /products to return all records
        if (item.getItemName() == null) {
            item.setItemName(""); // empty string signifies broadest possible search
        }

        // find products by name
        List<Item> results = itemRepo.findByItemName(item.getItemName());
        if (results.isEmpty()) {
            // no products found
            result.rejectValue("name", "notFound", "not found");
            return "finditem";
        } else if (results.size() == 1) {
            // 1 product found
            item = results.iterator().next();
            model.put("item", item);
            return "showitem";
        } else {
            // multiple products found
            model.put("items", results);
            return "showitems";
        }

    }

无论我似乎做什么,我都只能让函数在测试时返回“finditem”。到目前为止,我在课堂上将其作为我的代码进行测试。

@Mock
    Model model;
    @Mock
    Item item;
    @Mock
    Item item2;
    @Mock
    ItemRepository itemRepo;
    @Mock
    Map<String,Object> mockMap;
    @Mock
    BindingResult mockResult;
    @Mock
    List<Item> results;
    
    @InjectMocks

@Test
    public void testFindByItemNameReturnsFindItemWhenListLengthOne() {
        
        results.add(item);
        String expectedValue = "showitem";
        String actualValue = itemController.processFindForm(item, mockResult, mockMap);
        
        Assert.assertEquals(expectedValue, actualValue);
    }
    
    @Test
    public void testFindByItemNameReturnsFindItemWhenListLengthTwo() {
        List<Item> results = new ArrayList<>();
        
        results.add(item2);
        results.add(item2);
        System.out.print(results.size());
        String expectedValue = "showitems";
        String actualValue = itemController.processFindForm(item, mockResult, mockMap);
        
        Assert.assertEquals(expectedValue, actualValue);
    }

如何将结果“注入”(如果这是正确的词)到函数中以更改我的实际值?

提前致谢

1 个答案:

答案 0 :(得分:0)

如果您想单独测试您的 ItemController,我建议您模拟它对 ItemRepositoy 的依赖。 您如何执行此操作取决于您是要编写集成测试还是单元测试。

我个人更喜欢用集成测试来测试控制器。 Spring Boot 提供了 @WebMvcTest Annotation,它在您的测试中禁用了全自动配置,而是仅配置您的 Web 层所需的组件。

您的测试将如下所示:

@WebMvcTest
class ItemControllerTest {

    @MockBean
    private ItemRepository itemRepository;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void cleverTestName() throws Exception {
        // mock behaviour of itemRepository
        doReturn(Collections.emptyList()).when(itemRepository).findByItemName(anyString());

        //make request to the controller and check results
        mockMvc.perform(...)
                .andExpect(...);
    }
}

通过此设置,您可以编写测试来检查您的响应。 有关 @WebMvcTest 的更多信息,我建议 one of my own Blogpost 关于该主题:)

相关问题