SpringMVC单元测试 - 不调用服务方法

时间:2015-01-30 05:56:34

标签: spring spring-security mockito junit4

当我通过模拟服务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);
    }
}

3 个答案:

答案 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。

文档:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-testing-spring-boot-applications-mocking-beans