在本教程中,我们将学习如何将 unit testing 添加到我们在本教程中讨论的基本 Spring Boot 应用程序中使用 SpringBoot 和 JPA 教程
本教程的起点将是一个 Web 应用程序的基本模板,其中包括 web、data-jpa、h2 和 thymeleaf 依赖项:
$ spring init -dweb,data-jpa,h2,thymeleaf samplewebapp
我们的项目结构如下所示:
~/springboot:$ tree samplewebapp/
samplewebapp/
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── samplewebapp
│ │ └── DemoApplication.java
│ └── resources
│ ├── application.properties
│ ├── static
│ └── templates
└── test
└── java
└── com
└── example
└── samplewebapp
└── DemoApplicationTests.java
在这个项目中,已经有一个 Tester 类,其中包含一个最小的 Test :
package com.example.samplewebapp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
@Test
public void contextLoads() {}
}
以上是一个示例默认测试类。让我们检查一下:
@RunWith(SpringRunner.class) :此注解是 JUnit 库的自定义扩展,它将调用它所引用的类(SpringRunner.class)
@SpringBootTest 注释告诉 Spring Boot 去寻找一个主配置类(例如一个带有 @SpringBootApplication 的配置类),并使用它来启动一个 Spring 应用程序上下文
@Test:这是一个标准的 JUnit 测试注解,将在测试开始时执行该方法。您可以有一种或多种方法。如果您有多个带有该注释的方法,则不能保证它们将按该顺序执行。为此,您需要在类中添加 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 注释。
此外,需要注意的一件事是 Spring initializr 已经为您提供了在项目中运行测试所需的库:
<?xml version="1.0" encoding="UTF-8"?><project>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</project>
您可以在 IDE 或命令行(mvn test
或 gradle test
)上运行此测试,它应该会通过。
测试 Spring Boot 应用程序主要有两种策略:您可以使用 MockMVC 方法编写 Controller 测试,或者使用 RestTemplate。第一个策略 (MockMVC) 将在此处显示,如果您想编写 ***real***Unit Test 代码,它应该是您的选择。另一方面,如果您打算编写集成测试,则应使用 RestTemplate 策略。
所以,这是我们的基本控制器:
package com.example.samplewebapp;
import java.net.URI;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
@RestController
public class PersonController {
@Autowired private PersonRepository repository;
@GetMapping("/all")
public Iterable<Person> retrieveAllPersons() {
return repository.findAll();
}
@GetMapping("/person/{id}")
public Person retrieveStudent(@PathVariable long id) {
Optional<Person> person = repository.findById(id);
if (!person.isPresent()) throw new RuntimeException("id-" + id);
return person.get();
}
@PostMapping("/add")
public ResponseEntity<Object> createStudent(@RequestBody Person person) {
person = repository.save(person);
URI location =
ServletUriComponentsBuilder.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(person.getId())
.toUri();
return ResponseEntity.created(location).build();
}
}
我们现在将使用 MockMVC 编写一个最小的测试类:
package com.example.samplewebapp;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
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.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.fasterxml.jackson.databind.ObjectMapper;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class DemoApplicationTests {
@Autowired private MockMvc mvc;
@Test
public void checkAll() throws Exception {
mvc.perform(get("/all").contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].name", is("Jack")));
}
@Test
public void findById() throws Exception {
mvc.perform(get("/person/{id}", 1))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$.id", is(1)))
.andExpect(jsonPath("$.name", is("Jack")));
}
@Test
public void add() throws Exception {
Person user = new Person("Mark", "Stark");
mvc.perform(post("/add").contentType(MediaType.APPLICATION_JSON).content(asJsonString(user)))
.andExpect(status().isCreated());
}
public static String asJsonString(final Object obj) {
try {
return new ObjectMapper().writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
在此示例中,我们使用注释 @AutoConfigureMockMvc。此注解告诉 SpringRunner 配置将用于进行 REST 调用的 MockMvc 实例。 MockMvc 允许我们测试我们的 @RestController 类,而无需启动 Web 服务器。
然后我们使用类 MockMVC 的方法 perform 来执行实际的 REST 调用。您可以在 IDE Run As > JUnitTest 中运行上述测试,也可以使用命令行中的“spring test”运行上述测试:
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
内容来源于网络,如有侵权,请联系作者删除!