使用 spring-test-mvc 单元测试 REST 控制器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10636569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 05:07:34  来源:igfitidea点击:

Unit testing REST Controller with spring-test-mvc

springunit-testingspring-mvcspring-test

提问by CFL_Jeff

I have upgraded my Spring dependency to Spring 3.1.1.RELEASE and I'm trying to use spring-test-mvcto unit test a simple Controller. I have been following the technique used in Spring REST Controller Test with spring-test-mvc framework, since it seems to have worked for that person, but I have been unsuccessful so far. I think there's some key configuration I"m missing in my test context file.

我已将我的 Spring 依赖项升级到 Spring 3.1.1.RELEASE,并且我正在尝试使用spring-test-mvc对一个简单的控制器进行单元测试。我一直在使用spring-test-mvc framework跟踪Spring REST Controller Test 中使用的技术,因为它似乎对那个人有用,但到目前为止我没有成功。我认为我的测试上下文文件中缺少一些关键配置。

I get no errors. The reason I know it's not working is because Hello Worldnever gets printed (see Controller). What am I missing here?

我没有错误。我知道它不起作用的原因是因为Hello World永远不会被打印(请参阅控制器)。我在这里缺少什么?

Controller:

控制器:

@Controller
@RequestMapping("/debug")
public class DebugOutputController {

    @RequestMapping(method = RequestMethod.POST)
    public void saveDebugOutput(@RequestBody DebugOutput debugOutput, HttpServletResponse response) {
        System.out.println("Hello World");
    }
}

Test Class:

测试类:

@RunWith(SpringJUnit4ClassRunner.class) //this lets tests access Spring beans defined in the context config file
@ContextConfiguration(locations={"file:src/test/resources/itest/restAPITestContext.xml"}) //tells the test where to get configuration and beans to be used by the test.
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,  TransactionalTestExecutionListener.class}) //overrides the default stack of listeners
public class ITRestAPI{

@Autowired
private DebugOutputController debugOutputController;

private MockMvc mockMvc;

@Before
public void setUp() throws Exception {
    mockMvc = MockMvcBuilders.standaloneSetup(debugOutputController).build();
}

@After
public void tearDown() throws Exception {
}

@Test
public void shouldPerformPost() throws Exception {
    this.mockMvc.perform(post("/debug"));
}
}

restAPITestContext.xml:

restAPITestContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <mvc:annotation-driven />
    <mvc:default-servlet-handler />
    <context:component-scan resource-pattern="*DebugOutputController*" base-package="com.company.project.servlet" />    

</beans>

回答by CFL_Jeff

Turns out an HttpMessageNotReadableexception was occurring and I just couldn't see it because I was not logging or printing it anywhere. I found it by building the HTTP request in my test class using the DefaultRequestBuilderclass and adding a andDo(print()):

结果发生了HttpMessageNotReadable异常,我只是看不到它,因为我没有在任何地方记录或打印它。我通过使用DefaultRequestBuilder该类在我的测试类中构建 HTTP 请求并添加一个andDo(print())

DefaultRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/debug").contentType(MediaType.APPLICATION_JSON).body(new String("{\"T1\":109.1, \"T2\":99.3}").getBytes());
this.mockMvc.perform(requestBuilder).andDo(print());

So after that, using the output of andDo(print()), I could see that the HttpMessageNotReadableexception was being thrown, but didn't know the details of the exception or what was causing it. To see the details, I had to add this to the controller class to write the exception details to the response body:

所以在那之后,使用 的输出andDo(print()),我可以看到HttpMessageNotReadable正在抛出异常,但不知道异常的详细信息或导致它的原因。要查看详细信息,我必须将其添加到控制器类以将异常详细信息写入响应正文:

@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseBody
public String handleException1(HttpMessageNotReadableException ex)
{
    return ex.getMessage();
}

This revealed the following exception:

这揭示了以下异常:

Could not read JSON: Unrecognized field "T1" (Class com.company.project.model.device.DebugOutput), not marked as ignorable

which I fixed by adding the @JsonPropertyannotation to the setters in my model class:

我通过将@JsonProperty注释添加到我的模型类中的 setter 来修复它:

@JsonProperty("T1")
public void setT1(Float t1) {
    T1 = t1;
}