使用MockMvc测试SpringBoot

时间:2019-02-05 21:04:14

标签: java spring spring-boot testing mocking

我在MockMvc(使用Spring Boot)中遇到问题。我有一个小的代码来学习测试

import static org.hamcrest.Matchers.containsString;
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.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class ApplicationTest04_ownServer {

@Autowired
private MockMvc mockMvc;

@Test
public void shouldReturnDefaultMessage() throws Exception {
    this.mockMvc
    .perform(get("/"))
    .andDo(print())
    .andExpect(status().isOk())
    .andExpect(content().string(containsString("Hello")));
}

好。 Mi pom.xml是这个

[...]
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.19.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>org.springframework</groupId>
<artifactId>Prueba</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Prueba</name>

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>compile</scope>
    </dependency>

</dependencies>

我有几次测试。的作品,但我对模拟对象或类似的测试有问题。例如,在测试中,控制器向我回复了一条文本。

@Controller
public class HomeController {

    @RequestMapping("/")
    public @ResponseBody String greeting() {
        return "Hello";
    }

}

在测试中(上面的第一个代码),这是代码

@Test
public void shouldReturnDefaultMessage() throws Exception {
    this.mockMvc
    .perform(get("/"))
    .andDo(print())
    .andExpect(status().isOk())
    .andExpect(content().string(containsString("Hello")));
}

因此,我希望控制器的响应与测试(“ hello”)的响应相同,但是Junit测试是错误的。

java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match 

我打印结果

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /
       Parameters = {}
          Headers = {}

Handler:
             Type = hello.HomeController
           Method = public java.lang.String hello.HomeController.greeting()

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

    ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
         Headers = {Content-Type=[text/plain;charset=UTF-8], Content-Length=[5]}
     Content type = text/plain;charset=UTF-8
             Body = Hello
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /
       Parameters = {}
          Headers = {}

Handler:
             Type = hello.HomeController
           Method = public java.lang.String hello.HomeController.greeting()

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Content-Type=[text/plain;charset=UTF-8], Content-Length=[5]}
     Content type = text/plain;charset=UTF-8
             Body = Hello
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

身体反应是你好,不是吗? 有想法吗?

观察: 该示例在Eclipse Neon中有效,但是现在我使用的是Eclipse的最新版本。我遇到了很多错误(大多数类型都不会出现:MockMvc,SpringRunner,SpringBootTest等) 解决方案是更改依赖项的范围(测试->编译)。 现在是依赖项

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>compile</scope>
    </dependency>

与问题有关吗?

预先感谢

2 个答案:

答案 0 :(得分:1)

依赖项的范围应该仅是测试。 根据下面的maven文档,对scope = test的描述

  • 测试

此范围表示依赖关系对于正常使用应用程序不是必需的,并且仅在测试编译和执行阶段可用。

正如注释中突出显示的那样,不要使用war use jar。您可以删除tomcat依赖项,并且spring boot会看到spring Web依赖项并会自动提供嵌入式tomcat。 如果您打算仅测试控制器行为,则应使用Spring Boot测试片,在这种情况下为Web片。因此,您可以使用@WebMvcTest注释测试 下面是一个很好的例子,您一定要检查一下。

https://spring.io/guides/gs/testing-web/

希望这会有所帮助

答案 1 :(得分:0)

感谢克莱里斯病态儿子。现在可以使用

基于这些想法,我开发了一个新代码(只有Jar放入pom.xml中),并且将“测试依赖项”的范围设置为“测试”

[...]
<packaging>war</packaging>
[...]
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

我有一个特殊的问题,因为测试文件没有放入“测试包”中。我已将所有测试文件移至“测试包”。 出于好奇,它可以在Neon Eclipse中使用,而不是在最新版本中使用

我知道本示例中的(Test Tutorial of Spring)和大部分想法都属于本教程。

感谢您的回答。问题已结束