JUnit 在带有 @Autowired 注释的 Spring Boot 中不起作用

Posted

技术标签:

【中文标题】JUnit 在带有 @Autowired 注释的 Spring Boot 中不起作用【英文标题】:JUnit not working in Spring Boot with @Autowired annotation 【发布时间】:2018-12-30 02:11:12 【问题描述】:

我有一个 Spring Boot 应用程序,我正在其中创建 REST Web 服务 使用 MVC 模式。

我有一个控制器、服务和 DAO 类,我使用 @Autowired 注解来调用服务和 DAO 层的方法。

当我使用 mockito 创建 JUnit 测试时,值会进入控制器,但不会从控制器进入服务类。

这是代码示例:

@WebAppConfiguration
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = AppplicationConfiguration.class)
public class ExternalControllerTest 


    private MockMvc mockMvc;


    @InjectMocks
    private MyController myController;


    @MockBean
    myService myService;


    @Before
    public void setUp() throws Exception 
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders
                .standaloneSetup(myController)

                .build();
    


    @Test
    public void testListCluster() throws Exception 


        Input emrInput = new Input();
        emrInput.setId("200004773");
        emrInput.setName("test");

        String expected = "\"status\":\"Success\",\"message\":\"Success\",\"data\":\"somevalue\"";

        AutomateRestResponse response = new AutomateRestResponse<JsonObject>();

        response.setMessage("Success");
        response.setStatus("Success");
        response.setData("somevalue");
        Mockito.when(
                externalService.listCluster(emrInput)
        ).thenReturn(response);

        mockMvc.perform(post("/v1/gerData"))


                .andExpect(status().isOk())

                .andExpect(jsonPath("$.status", is("Success")));


        verify(externalService, times(1)).listCluster(emrInput);


        RequestBuilder requestBuilder = MockMvcRequestBuilders

                .post("/v4/listCluster")

                .accept(MediaType.APPLICATION_JSON).content(emrInputJosn)

                .contentType(MediaType.APPLICATION_JSON);


        MvcResult result = mockMvc.perform(requestBuilder).andReturn();


        System.out.println("response body1" + result.getResponse()

                .getContentAsString());
    `

请帮帮我。

【问题讨论】:

您正在尝试为哪个层创建测试? 请在您的帖子中添加minimal reproducible example。 你可以尝试用@RunWith(MockitoJUnitRunner.class)替换@RunWith(SpringJUnit4ClassRunner.class) 【参考方案1】:

从您的问题中不清楚您要模拟什么。

无论如何,您应该无法调试被模拟的服务/dao,因为在测试中实际执行的是模拟的而不是您的。

如果您想测试您的控制器,您可以模拟您的服务或 dao 并定义它们将返回的响应,然后验证您从控制器获得的响应是​​否符合您的预期。

【讨论】:

感谢您的回复。我有一个 josn 格式的 api(/getdata) 输入,例如 "id": "1","name": "manish","address": "mumbai" 这给了我响应 "status": "success ","消息", "数据": "123455". 如何粘贴代码,我无法粘贴代码 WebAppConfiguration RunWith(SpringJUnit4ClassRunner.class) ContextConfiguration(classes = Configuration.class) public class MyCloudControllerTest private MockMvc mockMvc; InjectMocks 私有 MyController 控制器;模拟 MyService 外部服务;在 public void setUp() 抛出 Exception MockitoAnnotations.initMocks(this); 之前mockMvc = MockMvcBuilders .standaloneSetup(Controller) .build(); @Test public void testMyController() throws Exception PersonInput personInput = new Person();个人输入 .setId("1"); personInput .setName("test"); personInput .setMarker("manish"); personInput .setAddress("孟买");字符串输入 = "\"id\": \"1\",\"name\": \"manish\",\"address\": \"mumbai\"" 字符串预期 = ""status" :“成功”,“消息”,“数据”:“123455”” AutomateRestResponse 响应 = 新 AutomateRestResponse(); response.setMessage("成功"); response.setStatus("状态"); response.setData("somevalue"); 请帮帮我【参考方案2】:

@EnableWebMvc @SpringBootApplication(scanBasePackages = "com.yourPackage.external" )

公共类 YourApplication 扩展 org.springframework.boot.web.support.SpringBootServletInitializer

public static void main(String[] args) 
    SpringApplication.run(applicationClass, args);


@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) 
    return application.sources(applicationClass);


private static Class<Application> applicationClass = Application.class;

【讨论】:

【参考方案3】:

根据您粘贴的内容,您可以执行以下操作:

    如果你使用@RunWith(SpringJUnit4ClassRunner.class) [最好改为@RunWith(SpringRunner.class)] 然后使用

    @MockBean private MyService externalService;

    使用@RunWith(MockitoJUnitRunner.class)

    @MockBean private MyService externalService;

@InjectMocks private MyController controller = new MyController(externalService);

查看详情:-testing web in spring boot

【讨论】:

我也试过这个,但它不起作用。我在下面粘贴我的测试类代码。 ExternalControllerTest.java 大家好,请帮帮我。我深陷其中【参考方案4】:
@WebAppConfiguration
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = AppplicationConfiguration.class)
public class ExternalControllerTest 


    private MockMvc mockMvc;


    @InjectMocks
    private MyController myController  ;



    @MockBean
    myService myService;



    @Before
    public void setUp() throws Exception 
          MockitoAnnotations.initMocks(this);
            mockMvc = MockMvcBuilders
                    .standaloneSetup(myController)

                    .build();
    


    @Test
    public void testListCluster() throws Exception 


Input emrInput = new Input();
emrInput.setId("200004773");
emrInput.setName("test");

String expected = "\"status\":\"Success\",\"message\":\"Success\",\"data\":\"somevalue\"";

AutomateRestResponse response =  new AutomateRestResponse<JsonObject>();

response.setMessage("Success");
response.setStatus("Success");
response.setData("somevalue");
Mockito.when(
        externalService.listCluster(emrInput)
                ).thenReturn(response);

mockMvc.perform(post("/v1/gerData"))


.andExpect(status().isOk())



.andExpect(jsonPath("$.status", is("Success")));



verify(externalService, times(1)).listCluster(emrInput);



RequestBuilder requestBuilder = MockMvcRequestBuilders

.post("/v4/listCluster")

.accept(MediaType.APPLICATION_JSON).content(emrInputJosn)

.contentType(MediaType.APPLICATION_JSON);



MvcResult result = mockMvc.perform(requestBuilder).andReturn();


System.out.println("response body1"+ result.getResponse()

.getContentAsString());


【讨论】:

这是你的测试课吗? 是的,我会输入这样的内容。 "id": "1234", "name": "manish" 输出我会得到 "\"status\":\"Success\",\"message\":\"Success\",\ "数据\":\"某个值\""; 你在用.post("/v4/listCluster")做什么? 我有一个名为 /v4/listCluster 的 api,它有 http post call,它在 myController 中

以上是关于JUnit 在带有 @Autowired 注释的 Spring Boot 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JUnit 中加载应用程序上下文并使用 Autowired

带有 @Suite 注释的 Junit5 测试套件不使用 mvn test 命令执行测试

如何在测试方法中使用@Autowired

Junit问题01 利用 @Autowired 注入失效问题

如何使 Spring 的 @Autowired 在 JUnit 5 扩展中工作? [复制]

@Autowired - 没有为依赖找到符合条件的 bean