本文介绍了Mockito是否应在Spring 4中与MockMvc的webAppContextSetup一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我一起使用webAppContextSetup时,很难使Mockito和MockMvc一起工作.我很好奇是否是因为我以一种他们从未打算过的方式将两者混合在一起.

I'm having difficulties getting Mockito and MockMvc working together when I use the webAppContextSetup together. I'm curious if it's because I'm mixing the two in a way they were never intended.

来源: https://github.com/zgardner/spring-boot-intro/blob/master/src/test/java/com/zgardner/springBootIntro/controller/PersonControllerTest.java

这是我正在运行的测试:

Here is the test I'm running:

package com.zgardner.springBootIntro.controller;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static java.lang.Math.toIntExact;
import static org.hamcrest.Matchers.is;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;

import com.zgardner.springBootIntro.Application;
import com.zgardner.springBootIntro.service.PersonService;
import com.zgardner.springBootIntro.model.PersonModel;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class PersonControllerTest {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Autowired
    private DefaultListableBeanFactory beanFactory;

    @Mock
    private PersonService personService;

    @InjectMocks
    private PersonController personController;

    @Before
    public void setup() {
        initMocks(this);

        // beanFactory.destroySingleton("personController");
        // beanFactory.registerSingleton("personController", personController);

        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void getPersonById() throws Exception {
        Long id = 999L;
        String name = "Person name";

        when(personService.findById(id)).thenReturn(new PersonModel(id, name));

        mockMvc.perform(get("/person/getPersonById/" + id))
            .andDo(print())
            .andExpect(jsonPath("$.id", is(toIntExact(id))))
            .andExpect(jsonPath("$.name", is(name)));
    }
}

我期望当mockMvc执行该HTTP调用的模拟时,它将使用我在测试中定义的PersonController.但是,当我调试通过时,它使用的是由SpringJunit4ClassRunner在测试启动时创建的PersonController.

I was expecting that when mockMvc performed the mock of that HTTP call, it would use the PersonController I defined in my test. But when I debug through, it's using the PersonController which was created by the SpringJunit4ClassRunner on the test boot up.

我发现了两种方法可以使它起作用:

I found two ways to get this to work:

  1. 注入bean工厂,删除旧的personController单例,然后添加我自己的.这很丑,我不是粉丝.
  2. 使用standaloneSetup而不是webAppContextSetup连接所有内容.我可以这样做,因为我不必接触bean工厂.

以下是我发现的一些与该主题有所不同的文章:

Here are some different articles I've found that somewhat touch on the topic:

  • Spring Tutorial - Building REST Services This just autowires in the repos to clear out the data before the integration test takes place.
  • Use Spring MVC Test framework and Mockito to test controllers This uses Mockito along with webAppContextSetup, but this is in Spring 3. (I'm using Spring Boot)
  • Unable to mock Service class in Spring MVC Controller tests This uses the standaloneSetup, which does work in my case too.

有想法吗?

推荐答案

您可能对新的测试功能(特别是新的@MockBean批注).这示例显示了如何模拟服务并将其与控制器测试一起使用.

You might be interested in the new testing features coming in Spring Boot 1.4 (specifically the new @MockBean annotation). This sample shows how a service can be mocked and used with a controller test.

这篇关于Mockito是否应在Spring 4中与MockMvc的webAppContextSetup一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 20:40