当我通过模拟服务bean在控制器上运行单元测试时,看起来根本没有调用服务方法。这是预期的behvaior还是我错过了什么?
SearchController.java
@Controller
public class SearchController {
@Autowired
SearchService searchService;
@RequestMapping(value="/search", method=RequestMethod.GET)
public String showSearchPage(Model model){
model.addAttribute("list", searchService.findAll());
return "search";
}
}
SearchControllerTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("file:src/main/webapp/WEB-INF/springapp-servlet.xml")
public class SearchControllerTest {
@Autowired
private WebApplicationContext webAppContext;
private MockMvc mockMvc;
private SearchService searchServiceMock;
@Before
public void setUp(){
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webAppContext).build();
this.searchServiceMock = Mockito.mock(SearchServiceImpl.class);
}
@Test
public void testShowSearchPage() throws Exception{
when(searchServiceMock.findAll())
.thenReturn(Arrays.asList("abc", "acb", "123"));
this.mockMvc.perform(get("/search.do"))
.andExpect(status().isOk())
.andExpect(view().name("search"))
.andExpect(forwardedUrl("/WEB-INF/jsp/search.jsp"))
.andExpect(model().attribute("list", hasSize(3)));
verify(searchServiceMock, times(1)).findAll(); //this test is failing
verifyNoMoreInteractions(searchServiceMock);
}
}
当我运行测试时,似乎没有调用findAll()方法并且它抛出异常。 “通缉但未调用searchServiceImpl.findAll()”
我在这里犯了什么错误?
-------------更新------------------
SearchControllerTestNew.java
public class SearchControllerTestNew {
@InjectMocks
SearchController searchController;
@Mock
SearchService searchServiceMock;
@Mock
View mockView;
MockMvc mockMvc;
@Before
public void setUp(){
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(searchController).setSingleView(mockView)
.build();
}
@Test
public void testShowSearchPage() throws Exception{
when(searchServiceMock.findAll())
.thenReturn(Arrays.asList("abc", "acb", "123"));
this.mockMvc.perform(get("/search.do"))
.andExpect(status().isOk())
.andExpect(view().name("search"))
.andExpect(model().attribute("list", hasSize(3)))
.andExpect(forwardedUrl("/WEB-INF/jsp/search.jsp"));//this fails now
verify(searchServiceMock, times(1)).findAll();
verifyNoMoreInteractions(searchServiceMock);
}
}
答案 0 :(得分:3)
虽然你已经嘲笑SearchService
它没有被注入控制器(至少从你共享的代码中看不出来)。
因此,verify(searchServiceMock, times(1)).findAll();
必然会失败,因为它确实从未被调用过。
看看@InjectMock如何注射嘲笑。
此外,您需要添加以下LOC以便整个工作
首先引入一个字段
@InjectMocks
private SearchController controller;
setUp()
添加中的第二
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
答案 1 :(得分:3)
您的SearchController
将使用自动装配的SearchService
(您的应用程序上下文的一部分)而不是您的模拟,请注意您创建了一个模拟但您没有在任何地方使用它,而是创建一个{{1}根据您的应用程序上下文。
解决方案是,使用独立设置,可以完全控制控制器及其依赖项的实例化和初始化:
MockMvc
在此示例中,我省略了一些MVC基础结构配置,请查看MockMvcBuilder
文档以获取进一步配置。
答案 2 :(得分:0)
您可以将@MockBean
用于模拟,然后它们将自动注入到Context。