我有一个SpringMVC项目。我要测试的我的FooController方法是:
@GetMapping("/view/{fooId}")
public String view(@PathVariable String fooId, Model model) throws FooNotFoundException, JsonProcessingException {
Foo foo = fooService.getFoo(fooId);
model.addAttribute("fooId", foo.getId());
model.addAttribute("foo", new ObjectMapper().writeValueAsString(foo));
return "foo/view";
}
我写的测试是:
public class FooControllerTest {
@Mock
private Foo mockFoo;
@Mock
private FooService mockFooService;
@InjectMocks
private FooController controller;
private MockMvc mockMvc;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
public void testView() throws Exception {
String fooId = "fooId";
when(mockFooService.getFoo(fooId)).thenReturn(mockFoo);
when(mockFoo.getId()).thenReturn(fooId);
mockMvc.perform(get("/foo/view/" + fooId))
.andExpect(status().isOk())
.andExpect(model().attribute("fooId", fooId))
.andExpect(model().attributeExists("foo"))
.andExpect(forwardedUrl("foo/view"));
}
}
此测试失败,java.lang.AssertionError: No ModelAndView found
。
当我调试测试时,当mockFoo
被new ObjectMapper.writeValueAsString()
给出时,我发现它出错了。所以我认为模拟对象无法序列化。我该如何解决这个问题,如何让我的测试通过?
model.addAttribute("foo", new ObjectMapper().writeValueAsString(foo));
,这样测试工作(但不是我希望我的方法工作的方式)!所以现在我知道这是出错的地方。 .andExpect(model().attributeExists("foo"))
,它仍然产生了上述AssertionError。答案 0 :(得分:0)
一位同事建议如下:不是使用mockFoo
,而是创建一个新的Foo对象并像这样使用它:
@Test
public void testView() throws Exception {
String fooId = "fooId";
Foo foo = new Foo(fooId);
when(mockFooService.getFoo(fooId)).thenReturn(foo);
mockMvc.perform(get("/foo/view/" + fooId))
.andExpect(status().isOk())
.andExpect(model().attribute("fooId", fooId))
.andExpect(model().attributeExists("foo"))
.andExpect(forwardedUrl("foo/view"));
}
这很有效。我一直认为你必须模拟你没有测试过的每个对象(所以在Controller中,你会模拟除控制器本身之外的所有东西)。但是因为Foo
是一个简单的POJO,所以不需要嘲笑它。
答案 1 :(得分:0)
在执行InjectMocks注释时尝试添加Spy注释
@InjectMocks
@Spy
private FooController controller;
是的,不要实例化ObjectMapper或控制器内的任何类。如果你这样做,你将被迫使用PowerMockito。尝试在@Ruben提及的控制器中注入它们。
注入依赖项总是更容易进行测试。