Spring Boot 2 单元测试
开发环境:IntelliJ IDEA 2019.2.2
Spring Boot版本:2.1.8
IDEA新建一个Spring Boot项目后,pom.xml默认包含了Web应用和单元测试两个依赖包。
如下:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
一、测试Web服务
1、新建控制器类 HelloController.cs
package com.example.demo.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/") public String index() { return "index"; } @RequestMapping("/hello") public String hello() { return "hello"; } }
2、新建测试类 HelloControllerTest.cs
下面WebEnvironment.RANDOM_PORT会启动一个真实的Web容器,RANDOM_PORT表示随机端口,如果想使用固定端口,可配置为
WebEnvironment.DEFINED_PORT,该属性会读取项目配置文件(如application.properties)中的端口(server.port)。
如果没有配置,默认使用8080端口。
package com.example.demo.controller; 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.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class HelloControllerTest { @Autowired private TestRestTemplate restTemplate; @Test public void testIndex(){ String result = restTemplate.getForObject("/",String.class); Assert.assertEquals("index", result); } @Test public void testHello(){ String result = restTemplate.getForObject("/",String.class); Assert.assertEquals("Hello world", result);//这里故意写错 } }
在HelloControllerTest.cs代码中右键空白行可选择Run ‘HelloControllerTest’,测试类里面所有方法。
(如果只想测试一个方法如testIndex(),可在testIndex()代码上右键选择Run ‘testIndex()’)
运行结果如下,一个通过,一个失败。
二、模拟Web测试
新建测试类 HelloControllerMockTest.cs
设置WebEnvironment属性为WebEnvironment.MOCK,启动一个模拟的Web容器。
测试方法中使用Spring的MockMvc进行模拟测试。
package com.example.demo.controller; 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; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import java.net.URI; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)//MOCK为默认值,也可不设置 @AutoConfigureMockMvc public class HelloControllerMockTest { @Autowired private MockMvc mvc; @Test public void testIndex() throws Exception{ ResultActions ra = mvc.perform(MockMvcRequestBuilders.get(new URI("/"))); MvcResult result = ra.andReturn(); System.out.println(result.getResponse().getContentAsString()); } @Test public void testHello() throws Exception{ ResultActions ra = mvc.perform(MockMvcRequestBuilders.get(new URI("/hello"))); MvcResult result = ra.andReturn(); System.out.println(result.getResponse().getContentAsString()); } }
右键Run ‘HelloControllerMockTest’,运行结果如下:
三、测试业务组件
1、新建服务类 HelloService.cs
package com.example.demo.service; import org.springframework.stereotype.Service; @Service public class HelloService { public String hello(){ return "hello"; } }
2、新建测试类 HelloServiceTest.cs
WebEnvironment属性设置为NONE,不会启动Web容器,只启动Spring容器。
package com.example.demo.service; 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; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) public class HelloServiceTest { @Autowired private HelloService helloService; @Test public void testHello(){ String result = helloService.hello(); System.out.println(result); } }
右键Run ‘HelloServiceTest’,运行结果如下:
四、模拟业务组件
假设上面的HelloService.cs是操作数据库或调用第三方接口,为了不让这些外部不稳定因素影响单元测试的运行结果,可使用mock来模拟
某些组件的返回结果。
1、新建一个服务类 MainService.cs
里面的main方法会调用HelloService的方法
package com.example.demo.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MainService { @Autowired private HelloService helloService; public void main(){ System.out.println("调用业务方法"); String result = helloService.hello(); System.out.println("返回结果:" + result); } }
2、新建测试类 MainServiceMockTest.cs
下面代码中,使用MockBean修饰需要模拟的组件helloService,测试方法中使用Mockito的API模拟helloService的hello方法返回。
package com.example.demo.service; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.BDDMockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class MainServiceMockTest { @MockBean private HelloService helloService; @Autowired private MainService mainService; @Test public void testMain(){ BDDMockito.given(this.helloService.hello()).willReturn("hello world"); mainService.main(); } }
右键Run ‘MainServiceMockTest’,运行结果如下:
五、IDEA项目结构图
相关文章