Unit Test in SpringBoot

此处的Unit Test in SpringBoot 包括:

 SpringApplication Test

Service Test

ControllerTest

测试项目结构如下:

 代码如下:

POM.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.study</groupId>
    <artifactId>SpringBootTest-2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringBootTest-2</name>
    <description>Demo project for Spring Boot</description>

    <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>
            <optional>true</optional>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
package com.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}
package com.app;

public class Book {

    private Integer id;
    private String name;
    private String author;

    public Integer getId() {
    return id;
    }

    public void setId(Integer id) {
    this.id = id;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getAuthor() {
    return author;
    }

    public void setAuthor(String author) {
    this.author = author;
    }
    
    public String toString() {
    return String.format("Book - id: %d, name: %s, author: %s", id,name,author);
    }
    
}
package com.app;

import java.awt.print.Book;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Controller {
    
    @Autowired
    HelloService helloService;
    

    @GetMapping("/hello")
    public String sayHi(String name) {
    return helloService.sayHello(name);
    }
    
    @PostMapping("/book")
    public String addBook(@RequestBody Book book) {
    return book.toString();
    }

    
}
package com.app;

import org.springframework.stereotype.Service;

@Service
public class HelloService {

    public String sayHello(String name) {
    return "Hello " + name + "!";
    }
}

UnitTest

package com.app;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringRunner;


@RunWith(SpringRunner.class)
public class ApplicationTests {

    @Test
    public void contextLoads() {
    }

}
package com.app;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.fasterxml.jackson.databind.ObjectMapper;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ControllerTest {
    MockMvc mvc;

    @Autowired //模拟ServletContext环境
    WebApplicationContext webApplicationContext;

    @Autowired
    HelloService helloService;

    @Before
    public void before() {
    mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void sayHiTest() throws Exception {
    String uri = "/hello";
    MvcResult mvcResult = mvc
        .perform(MockMvcRequestBuilders.get(uri).contentType(MediaType.APPLICATION_FORM_URLENCODED)
            .param("name", "World"))
        .andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print()) // 可以查看Request被处理的细节
        .andReturn();
    String content = mvcResult.getResponse().getContentAsString();
    String expectedContent = "Hello World!";
    Assert.assertEquals("错误,返回值和预期返回值不一致", expectedContent, content);
    }

    @Test
    public void addBookTest() throws Exception {
    ObjectMapper om = new ObjectMapper();
    Book book = new Book();
    book.setAuthor("罗贯中");
    book.setName("三国演义");
    book.setId(1);

    String param = om.writeValueAsString(book);
    String uri = "/book";
    MvcResult mvcResult = mvc
        .perform(MockMvcRequestBuilders.post(uri).contentType(MediaType.APPLICATION_JSON).content(param))
        .andExpect(MockMvcResultMatchers.status().isOk()).andReturn();
    
    String content = mvcResult.getResponse().getContentAsString();
    System.out.println(content);
    

    }

}
package com.app;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ControllerTestUseTestRestTemplate {
    
    /**
     * 如果要使用TestRestTemplate进行测试,需要将@SPringBootTest 中webEnvironment属性的默认值由
     * WebEnvironment.MOCK 修改为 WebEnvironment.DEFINED_PORT 或者 WebEnvironment.RANDOM_PORT
     * 因为这两种都是使用一个真实的Servlet环境而不是模拟的Servlet环境
     */
    @Autowired
    TestRestTemplate restTemplate;
    
    @Test
    public void sayHiTest2() {
    
    ResponseEntity<String> response = restTemplate.getForEntity("/hello?name={0}", String.class, "World");
    String expectedContent = "Hello World!";
    String content = response.getBody();
    Assert.assertEquals("错误,返回值和预期返回值不一致", expectedContent, content);
    }

}
package com.app;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import org.junit.Assert;

@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloServiceTest {

    @Autowired
    HelloService helloService;
    
    @Test
    public void sayHelloTest() {
    String hello = helloService.sayHello("World");
    Assert.assertEquals(hello, "Hello World!");
    }
    
}
package com.app;

import java.io.IOException;

import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.JsonTest;
import org.springframework.boot.test.json.JacksonTester;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@JsonTest //该注解将自动配置Jackson ObjectMapper @JsonComponent 以及 Jackson Modules
public class JSONTest {

    @Autowired
    JacksonTester<Book> jacksonTester;
    
    @Test
    public void testSerialize() throws IOException {
    Book book = new Book();
    book.setAuthor("罗贯中");
    book.setName("三国演义");
    book.setId(1);
    
    Assertions.assertThat(jacksonTester.write(book)).isEqualToJson("book.json");
    Assertions.assertThat(jacksonTester.write(book)).hasJsonPathStringValue("@.name");
    Assertions.assertThat(jacksonTester.write(book)).extractingJsonPathStringValue("@.name").isEqualTo("三国演义");
    }
    
    @Test
    public void testDeserialize() throws IOException {
    String content = "{ "id": 1, "name": "三国演义", "author": "罗贯中" }";
        Assertions.assertThat(jacksonTester.parseObject(content).getName()).isEqualTo("三国演义");
    }
}
package com.app;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

/**
 * https://www.guru99.com/create-junit-test-suite.html
 *
 */
@RunWith(Suite.class)
@SuiteClasses({ApplicationTests.class, ControllerTest.class, ControllerTestUseTestRestTemplate.class,
    HelloServiceTest.class, JSONTest.class})
public class SuiteTests {

}

book.json

{ "id": 1, "name": "三国演义", "author": "罗贯中" }
SuiteTests 的测试结果:
 
原文地址:https://www.cnblogs.com/luffystory/p/12072585.html