SpringBoot 测试
2019-03-01 本文已影响0人
独孤流
@Controller
、@RestController
、@Service
、@Repository
、@Component
RestController和Controller的区别
一、SpringBoot 网络接口测试
接口类:HelloController
package com.lonelyflow.dcoker.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class HelloController {
@RequestMapping("/hello")
public Map<String,Object> hello(Map<String,Object> params){
Map<String,Object> result = new HashMap<String, Object>();
result.put("name","hello");
result.put("nickname","独孤九剑");
return result;
}
}
测试类HelloControllerbTests
package com.lonelyflow.dcoker.Controller;
import com.lonelyflow.dcoker.controller.HelloController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
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.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
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;
@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloControllerbTests {
/**
@Test,把一个方法标记为测试方法
@Before,每一个测试方法执行前自动调用一次
@After,每一个测试方法执行完自动调用一次
@BeforeClass,所有测试方法执行前执行一次,在测试类还没有实例化就已经被加载,因此用 static 修饰
@AfterClass,所有测试方法执行前执行一次,在测试类还没有实例化就已经被加载,因此用 static 修饰
@Ignore,暂不执行该测试方法
@RunWith 当一个类用 @RunWith 注释或继承一个用 @RunWith 注释的类时,
JUnit 将调用它所引用的类来运行该类中的测试而不是开发者再去 JUnit 内部去构建它。我们在开发过程中使用这个特性看看。
*/
// 用于模拟网络请求的测试
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
}
/**
* 模拟网络的请求及打印
*/
@Test
public void getHelloWeb() throws Exception {
// // 发送请求并接收数据,然后打印消息
// mockMvc.perform(
// MockMvcRequestBuilders.post("/hello?name=小明")
// .accept(MediaType.APPLICATION_JSON_UTF8)
// ).andDo(print());
//
// // 模拟多参数
// mockMvc.perform(
// MockMvcRequestBuilders.post("/saveUser")
// .param("name","")
// .param("age","666")
// .param("pass","test")
// .accept(MediaType.APPLICATION_JSON_UTF8)
// ).andDo(print());
/**
* perform 构建一个请求,并且返回 ResultActions 实例,该实例则可以获取到请求的返回内容。
* params 构建请求时候的参数,也支持 param(key,value) 的方式连续添加。
* contentType(MediaType.APPLICATION_JSON_UTF8) 代表发送端发送的数据格式。
* accept(MediaType.APPLICATION_JSON_UTF8) 代表客户端希望接受的数据类型格式。
* mockMvc.perform() 建立 Web 请求。
* andExpect(...) 可以在 perform(...) 函数调用后多次调用,表示对多个条件的判断。
* status().isOk() 判断请求状态是否返回 200。
* andReturn 该方法返回 MvcResult 对象,该对象可以获取到返回的视图名称、返回的 Response 状态、获取拦截请求的拦截器集合等。
*/
// map的参数
final MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("id", "6");
params.add("hello", "world");
String responseString = mockMvc.perform(
MockMvcRequestBuilders.get("/hello")
// 设置参数
.params(params)
// 设置headers
// 代表发送端发送的数据格式
.contentType(MediaType.APPLICATION_JSON_UTF8)
// 代表客户端希望接受的数据类型格式
.accept(MediaType.APPLICATION_JSON_UTF8))
// 把请求及返回内容打印出来
.andDo(print())
// 添加表达式测试,测试状态是否正常
.andExpect(status().isOk())
// 判断返回文本是否包含
.andExpect(content().string(containsString("hello")))
// 判断返回文本是否相等
//.andExpect(content().string(equalTo("hello")))
// 返回值是json时判断的内容
.andExpect(MockMvcResultMatchers.jsonPath("$.nickname").value("独孤九剑"))
// 将response的content返回
.andReturn().getResponse().getContentAsString();
System.out.println("result : "+responseString);
}
}
二、service测试
测试的需要@Service
注解
service1:
接口HelloService.java
package com.lonelyflow.dcoker.service;
public interface HelloService {
public void sayHello();
}
实现HelloServiceImpl.java
,实现类一定要有@Service
注解
package com.lonelyflow.dcoker.service.impl;
import com.lonelyflow.dcoker.service.HelloService;
import org.springframework.stereotype.Service;
@Service
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello() {
System.out.println("hello service");
}
}
service2:
import org.springframework.stereotype.Service;
@Service
public class MyService {
public void sayHi(){
System.out.println("安好");
}
}
测试:service自动注入可以使用@Resource
也可以使用@Autowired
package com.lonelyflow.dcoker.Controller;
import com.lonelyflow.dcoker.service.HelloService;
import com.lonelyflow.dcoker.tool.MyService;
import org.junit.Rule;
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.rule.OutputCapture;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ServiceTests {
/**
* 测试自动注入服务
* @throws Exception
*/
// 自动注入
@Resource
private HelloService helloService;
@Autowired
private MyService myService;
// 搜集控制台打印的信息
@Rule
public OutputCapture outputCapture = new OutputCapture();
@Test
public void testService() throws Exception{
helloService.sayHello();
myService.sayHi();
assertThat(this.outputCapture.toString().contains("hello service")).isTrue();
}
}
读取properties
读取properties的类
package com.lonelyflow.dcoker.tool;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
// 关联的properties或yml文件路径,不指定默认加载@PropertySource("classpath:application.properties")
@PropertySource("classpath:other.properties")
// 指定加载的属性文件里前缀
@ConfigurationProperties(prefix = "other")
public class HelloProperties {
private String title;
private String url;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
测试的类
package com.lonelyflow.dcoker.Controller;
import com.lonelyflow.dcoker.tool.HelloProperties;
import com.lonelyflow.dcoker.tool.HelloYML;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
@RunWith(SpringRunner.class)
/**
* 测试类都需要添加
*/
@SpringBootTest
public class PropertiesTests {
@Test
public void hello() {
System.out.println("hello world");
}
/**
* 测试读取配置属性信息,自动注入
*/
// 对properties文件自动注入
@Value("${hello.title}")
private String title;
// 自动注入properties
@Resource
private HelloProperties helloProperties;
@Test
public void testProperties() throws Exception{
System.out.println("value hello.title:"+title);
System.out.println("Resource-property: title:"+helloProperties.getTitle());
System.out.println("Resource-property: url:"+helloProperties.getUrl());
}
}