【问题标题】:Junit for RestController - Assertion ErrorRestController 的 Junit - 断言错误
【发布时间】:2018-10-16 07:16:38
【问题描述】:

我创建了一个rest api并通过邮递员进行了测试,并且能够按预期获得成功响应。现在我已经为上述 api 创建了 Junit 测试用例,但是在执行获取“java.lang.AssertionError: Status expected: but was:”时。无法弄清楚为什么会发生此异常。

我是 Mockito 和 MockMVC 的新手,因此我们将不胜感激。

下面是我的测试类

package com.example.demo.hystricks;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.io.Serializable;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

import org.apache.commons.lang.SerializationUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import com.example.demo.DemoController;
import com.example.demo.DemoService;
import com.example.demo.InputModel;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = DemoController.class)
public class DemoControllerTest {

private MockMvc mockMvc;

@InjectMocks
private DemoController demoController;

@MockBean
private DemoService demoService;

@MockBean
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;

@Before
public void setUp() {

    MockitoAnnotations.initMocks(this);
    DemoController demoController = new DemoController(demoService);
    this.mockMvc = MockMvcBuilders
            .standaloneSetup(demoController).
            setMessageConverters(mappingJackson2HttpMessageConverter).build();

}

@Test
public void postData() throws Exception {

    InputModel inputModel = new InputModel("12345","Test","CSC",getEventTime());
    System.out.println("before api....");
    RequestBuilder requestBuilder  = MockMvcRequestBuilders.post("/demoService")
            .accept(MediaType.APPLICATION_JSON)
            .content(inputModel.toString())
            .contentType(MediaType.APPLICATION_JSON);
    mockMvc.perform(requestBuilder)
    .andDo(MockMvcResultHandlers.print())
    .andExpect(status().isOk());
    System.out.println("after api....");
}

private LocalDateTime getEventTime() {

    Instant instant = Instant.ofEpochMilli(Instant.now().toEpochMilli());
    LocalDateTime eventTimestamp = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    return eventTimestamp;
}

}

我的休息控制器

@RestController
public class DemoController {

private static final Logger LOGGER = LoggerFactory.getLogger(DemoController.class);

public final DemoService demoService;

public DemoController(DemoService demoService) {
    this.demoService = demoService;
}

@RequestMapping(value = "demoService",method = RequestMethod.POST)
public ResponseEntity<String> postData(
        @RequestBody InputModel inputModel){

    LOGGER.info("DemoService Entered successfully");
    demoService.postData(inputModel.getId(),inputModel.getName(),
            inputModel.getDepartment(), inputModel.getJoinDate());
    LOGGER.info("DemoService Exited successfully");
    return new ResponseEntity<String>("success",HttpStatus.OK) ;
}

}

api 之前的控制台消息:

>2018-10-16 12:15:49.391  WARN 6200 --- [           main] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported]
2018-10-16 12:15:49.437  INFO 6200 --- [       Thread-3] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@5023bb8b: startup date [Tue Oct 16 12:15:48 IST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@76a4ebf2

故障堆栈跟踪:

>java.lang.AssertionError: Status expected:<200> but was:<415>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:619)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:178)
at com.example.demo.hystricks.DemoControllerTest.postData(DemoControllerTest.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

【问题讨论】:

  • 你的测试是错误的。删除您的 @Before 方法,spring 会为您完成所有这些。从测试中删除DemoController 和MappingJackson2HttpMessageConverter 字段并将@AUtowired 添加到您的MockMvc 字段。您想要一个 Web 切片测试,但正在围绕该框架努力工作。最后我怀疑inputModel.toString() 会创建一个有效的 JSON 正文。

标签: java spring spring-boot junit


【解决方案1】:

问题出在这一行:

 @MockBean
 private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;

你在嘲笑这个转换器。改为使用 new 创建一个实例:

this.mockMvc = MockMvcBuilders
        .standaloneSetup(controller).
        setMessageConverters(new MappingJackson2HttpMessageConverter()).build();

或者正如 M. Dienum 正确提到的,您可以从 setUp() 方法中删除以下两行代码,它会起作用:

DemoController demoController = new DemoController(demoService);
this.mockMvc = MockMvcBuilders
        .standaloneSetup(demoController).
        setMessageConverters(mappingJackson2HttpMessageConverter).build();

执行完所有这些操作后,如果遇到 400 错误,那么您的 toString() 方法就不会生成有效的 json。

【讨论】:

  • 我已经删除了@MockBean private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;而是创建了新实例。有效。感谢 M.Dienum 和 Aditya
  • 非常感谢!,我试图找到一种方法来通过指定我想用来测试的类来限制 Spring Boot 上下文,但是在我这样做的那一刻,一些自动配置被遗漏了对于 MockMvc,我做了你提到的关于创建映射 jackson 的新实例并添加它的方法,它就像一个魅力! ``` this.mockMvc = MockMvcBuilders .standaloneSetup(控制器)。 setMessageConverters(new MappingJackson2HttpMessageConverter()).build(); ```
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
相关资源
最近更新 更多