Mockito when().thenReturn() 在应该 return 空列表时返回 Null
Mockito when().thenReturn() Returning Null when it should return empty list
我一直在试图弄清楚为什么我的模拟 findIngredientsByCategory 方法 returning null 当我有 when(controller.findIngredientsByCategory(any()).thenReturn(Collections.emptyList())
时。此实现适用于 findAll 方法。
下面是我的单元测试实现:
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(IngredientController.class)
@ContextConfiguration(classes = {TestContext.class, WebApplicationContext.class})
@WebAppConfiguration
public class IngredientControllerTest {
@Autowired
private WebApplicationContext context;
@Autowired
private MockMvc mvc;
@MockBean
private IngredientController ingredientController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Autowired
private ObjectMapper mapper;
private static class Behavior {
IngredientController ingredientController;
public static Behavior set(IngredientController ingredientController) {
Behavior behavior = new Behavior();
behavior.ingredientController = ingredientController;
return behavior;
}
public Behavior hasNoIngredients() {
when(ingredientController.getAllIngredients()).thenReturn(Collections.emptyList());
when(ingredientController.getIngredientsByCategory(any())).thenReturn(Collections.emptyList());
when(ingredientController.getIngredientById(anyString())).thenReturn(Optional.empty());
return this;
}
}
@Test
public void getIngredientsByCategoryNoIngredients() throws Exception {
Behavior.set(ingredientController).hasNoIngredients();
MvcResult result = mvc.perform(get("/ingredients/filter=meat"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
String content = result.getResponse().getContentAsString();
System.out.println(content);
}
下面是控制器的实现:
@RestController
@RequestMapping("/ingredients")
public class IngredientController {
@Autowired
private IngredientRepository repository;
@RequestMapping(value = "/filter", method = RequestMethod.GET)
public List getIngredientsByCategory(@RequestParam("category") String category) {
return repository.findByCategory(category);
}
}
当我告诉它 return 一个空列表时,我不确定为什么模拟控制器在这个请求中 return 为 null。如果有人可以帮忙解决这个问题,我将不胜感激!谢谢
MockMvc
实际上会调用由 Spring 测试框架引导和创建的 IngredientController
但不会调用您用 [= 注释的模拟 IngredientController
14=],所以你所做的所有存根都不会被调用。
其实@WebMvcTest
的目的是为了测试@RestController
及其相关的Spring配置是否正确,所以需要一个IngredientController
的真实实例来创建而不是使用模拟的。相反,您应该模拟 IngredientController
(即 IngredientRepository
)内的依赖项。
因此,代码应如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(IngredientController.class)
@ContextConfiguration(classes = {TestContext.class, WebApplicationContext.class})
@WebAppConfiguration
public class IngredientControllerTest {
@Autowired
private WebApplicationContext context;
@Autowired
private MockMvc mvc;
@MockBean
private IngredientRepository ingredientRepository;
@Test
public void fooTest(){
when(ingredientRepository.findByCategory(any()).thenReturn(Collections.emptyList())
//And use the MockMvc to send a request to the controller,
//and then assert the returned MvcResult
}
}
测试中的请求路径是“/ingredients/filter=meat”,但应该是“/ingredients/filter?category=meat”。所以,似乎 getIngredientsByCategory
没有被调用。
我一直在试图弄清楚为什么我的模拟 findIngredientsByCategory 方法 returning null 当我有 when(controller.findIngredientsByCategory(any()).thenReturn(Collections.emptyList())
时。此实现适用于 findAll 方法。
下面是我的单元测试实现:
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(IngredientController.class)
@ContextConfiguration(classes = {TestContext.class, WebApplicationContext.class})
@WebAppConfiguration
public class IngredientControllerTest {
@Autowired
private WebApplicationContext context;
@Autowired
private MockMvc mvc;
@MockBean
private IngredientController ingredientController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Autowired
private ObjectMapper mapper;
private static class Behavior {
IngredientController ingredientController;
public static Behavior set(IngredientController ingredientController) {
Behavior behavior = new Behavior();
behavior.ingredientController = ingredientController;
return behavior;
}
public Behavior hasNoIngredients() {
when(ingredientController.getAllIngredients()).thenReturn(Collections.emptyList());
when(ingredientController.getIngredientsByCategory(any())).thenReturn(Collections.emptyList());
when(ingredientController.getIngredientById(anyString())).thenReturn(Optional.empty());
return this;
}
}
@Test
public void getIngredientsByCategoryNoIngredients() throws Exception {
Behavior.set(ingredientController).hasNoIngredients();
MvcResult result = mvc.perform(get("/ingredients/filter=meat"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
String content = result.getResponse().getContentAsString();
System.out.println(content);
}
下面是控制器的实现:
@RestController
@RequestMapping("/ingredients")
public class IngredientController {
@Autowired
private IngredientRepository repository;
@RequestMapping(value = "/filter", method = RequestMethod.GET)
public List getIngredientsByCategory(@RequestParam("category") String category) {
return repository.findByCategory(category);
}
}
当我告诉它 return 一个空列表时,我不确定为什么模拟控制器在这个请求中 return 为 null。如果有人可以帮忙解决这个问题,我将不胜感激!谢谢
MockMvc
实际上会调用由 Spring 测试框架引导和创建的 IngredientController
但不会调用您用 [= 注释的模拟 IngredientController
14=],所以你所做的所有存根都不会被调用。
其实@WebMvcTest
的目的是为了测试@RestController
及其相关的Spring配置是否正确,所以需要一个IngredientController
的真实实例来创建而不是使用模拟的。相反,您应该模拟 IngredientController
(即 IngredientRepository
)内的依赖项。
因此,代码应如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(IngredientController.class)
@ContextConfiguration(classes = {TestContext.class, WebApplicationContext.class})
@WebAppConfiguration
public class IngredientControllerTest {
@Autowired
private WebApplicationContext context;
@Autowired
private MockMvc mvc;
@MockBean
private IngredientRepository ingredientRepository;
@Test
public void fooTest(){
when(ingredientRepository.findByCategory(any()).thenReturn(Collections.emptyList())
//And use the MockMvc to send a request to the controller,
//and then assert the returned MvcResult
}
}
测试中的请求路径是“/ingredients/filter=meat”,但应该是“/ingredients/filter?category=meat”。所以,似乎 getIngredientsByCategory
没有被调用。