@Controller
父虑、@RestController
单山、@Service
、@Repository
悠砚、@Component
RestController和Controller的區(qū)別
一晓勇、SpringBoot 網(wǎng)絡(luò)接口測(cè)試
接口類: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","獨(dú)孤九劍");
return result;
}
}
測(cè)試類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,把一個(gè)方法標(biāo)記為測(cè)試方法
@Before灌旧,每一個(gè)測(cè)試方法執(zhí)行前自動(dòng)調(diào)用一次
@After绑咱,每一個(gè)測(cè)試方法執(zhí)行完自動(dòng)調(diào)用一次
@BeforeClass,所有測(cè)試方法執(zhí)行前執(zhí)行一次枢泰,在測(cè)試類還沒有實(shí)例化就已經(jīng)被加載描融,因此用 static 修飾
@AfterClass,所有測(cè)試方法執(zhí)行前執(zhí)行一次衡蚂,在測(cè)試類還沒有實(shí)例化就已經(jīng)被加載窿克,因此用 static 修飾
@Ignore,暫不執(zhí)行該測(cè)試方法
@RunWith 當(dāng)一個(gè)類用 @RunWith 注釋或繼承一個(gè)用 @RunWith 注釋的類時(shí)毛甲,
JUnit 將調(diào)用它所引用的類來運(yùn)行該類中的測(cè)試而不是開發(fā)者再去 JUnit 內(nèi)部去構(gòu)建它年叮。我們?cè)陂_發(fā)過程中使用這個(gè)特性看看。
*/
// 用于模擬網(wǎng)絡(luò)請(qǐng)求的測(cè)試
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
}
/**
* 模擬網(wǎng)絡(luò)的請(qǐng)求及打印
*/
@Test
public void getHelloWeb() throws Exception {
// // 發(fā)送請(qǐng)求并接收數(shù)據(jù)玻募,然后打印消息
// mockMvc.perform(
// MockMvcRequestBuilders.post("/hello?name=小明")
// .accept(MediaType.APPLICATION_JSON_UTF8)
// ).andDo(print());
//
// // 模擬多參數(shù)
// mockMvc.perform(
// MockMvcRequestBuilders.post("/saveUser")
// .param("name","")
// .param("age","666")
// .param("pass","test")
// .accept(MediaType.APPLICATION_JSON_UTF8)
// ).andDo(print());
/**
* perform 構(gòu)建一個(gè)請(qǐng)求只损,并且返回 ResultActions 實(shí)例,該實(shí)例則可以獲取到請(qǐng)求的返回內(nèi)容七咧。
* params 構(gòu)建請(qǐng)求時(shí)候的參數(shù)改执,也支持 param(key,value) 的方式連續(xù)添加。
* contentType(MediaType.APPLICATION_JSON_UTF8) 代表發(fā)送端發(fā)送的數(shù)據(jù)格式坑雅。
* accept(MediaType.APPLICATION_JSON_UTF8) 代表客戶端希望接受的數(shù)據(jù)類型格式辈挂。
* mockMvc.perform() 建立 Web 請(qǐng)求。
* andExpect(...) 可以在 perform(...) 函數(shù)調(diào)用后多次調(diào)用裹粤,表示對(duì)多個(gè)條件的判斷终蒂。
* status().isOk() 判斷請(qǐng)求狀態(tài)是否返回 200。
* andReturn 該方法返回 MvcResult 對(duì)象遥诉,該對(duì)象可以獲取到返回的視圖名稱拇泣、返回的 Response 狀態(tài)、獲取攔截請(qǐng)求的攔截器集合等矮锈。
*/
// map的參數(shù)
final MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("id", "6");
params.add("hello", "world");
String responseString = mockMvc.perform(
MockMvcRequestBuilders.get("/hello")
// 設(shè)置參數(shù)
.params(params)
// 設(shè)置headers
// 代表發(fā)送端發(fā)送的數(shù)據(jù)格式
.contentType(MediaType.APPLICATION_JSON_UTF8)
// 代表客戶端希望接受的數(shù)據(jù)類型格式
.accept(MediaType.APPLICATION_JSON_UTF8))
// 把請(qǐng)求及返回內(nèi)容打印出來
.andDo(print())
// 添加表達(dá)式測(cè)試霉翔,測(cè)試狀態(tài)是否正常
.andExpect(status().isOk())
// 判斷返回文本是否包含
.andExpect(content().string(containsString("hello")))
// 判斷返回文本是否相等
//.andExpect(content().string(equalTo("hello")))
// 返回值是json時(shí)判斷的內(nèi)容
.andExpect(MockMvcResultMatchers.jsonPath("$.nickname").value("獨(dú)孤九劍"))
// 將response的content返回
.andReturn().getResponse().getContentAsString();
System.out.println("result : "+responseString);
}
}
二、service測(cè)試
測(cè)試的需要@Service
注解
service1:
接口HelloService.java
package com.lonelyflow.dcoker.service;
public interface HelloService {
public void sayHello();
}
實(shí)現(xiàn)HelloServiceImpl.java
,實(shí)現(xiàn)類一定要有@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("安好");
}
}
測(cè)試:service自動(dòng)注入可以使用@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 {
/**
* 測(cè)試自動(dòng)注入服務(wù)
* @throws Exception
*/
// 自動(dòng)注入
@Resource
private HelloService helloService;
@Autowired
private MyService myService;
// 搜集控制臺(tái)打印的信息
@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
// 關(guān)聯(lián)的properties或yml文件路徑,不指定默認(rèn)加載@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;
}
}
測(cè)試的類
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)
/**
* 測(cè)試類都需要添加
*/
@SpringBootTest
public class PropertiesTests {
@Test
public void hello() {
System.out.println("hello world");
}
/**
* 測(cè)試讀取配置屬性信息苞笨,自動(dòng)注入
*/
// 對(duì)properties文件自動(dòng)注入
@Value("${hello.title}")
private String title;
// 自動(dòng)注入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());
}
}