SpringBoot單元測試

針對不一樣的代碼層次, 有不一樣的測試注意事項.web

個人理解是:spring

針對Mapper層或者是Dao層,因爲須要跟數據庫交互, 寫完代碼的時候手工執行就好, 因爲數據庫的數據的不穩定性,不適合用做大量回歸測試.數據庫

針對Service層的單元測試纔是咱們一般理解的那種單元測試或者說白盒測試.mvc

針對Controller層的測試,若是Mock了Service層的行爲,那這個算是白盒測試,若是沒有Mock Service層行爲,而是直接調用,我以爲其實已經能夠算是集成測試了,這個偏向黑盒測試的範疇,就是咱們一般說的API測試.app

 

1. 針對Mapper層或者Dao層ide

若是是有依賴其餘Bean對象,能夠先寫一個專門用來裝配Bean的類,並用註解TestConfiguration標註.單元測試

固然,這一步也不是必須的,這個只是爲了方便在單元測試類中使用@Autowired引入對象.能夠在單元測試類中,使用Product product = new Product()代替.測試

 1 import org.springframework.boot.test.context.TestConfiguration;
 2 import org.springframework.context.annotation.Bean;
 3 
 4 import com.windy.mall.product.bean.Product;
 5 
 6 @TestConfiguration
 7 public class TestBeanConfiguration {
 8 
 9     @Bean
10     public Product createProduct(){
11         return new Product();
12     }
13     
14 }
View Code

 

單元測試類中必需要聲明:ui

(1) @RunWith(Spring.class),表示要在Spring環境中作測試, 因而就可使用@Autowired等註解了,spa

(2) @SpringBootTest(classes=TestBeanConfiguration.class),表示可使用SpringBoot環境了,這樣能夠用@Autowired註解,把@Mapper註釋過的Mapper對象引入.爲了引入外部依賴的Bean對象,須要指定classes=TestBeanConfiguration.class.

注意: 之因此要指定classes=TestBeanConfiguration.class,這時由於Product這個類,並無使用@Component等註解注入IOC容器.

可選:

(3) @Transactional註解來開啓事務

(4) @Rollback(true)表示開啓回滾數據功能,默認爲True.

 1 import org.junit.Assert;
 2 import org.junit.Before;
 3 import org.junit.Test;
 4 import org.junit.runner.RunWith;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.boot.test.context.SpringBootTest;
 7 import org.springframework.test.annotation.Rollback;
 8 import org.springframework.test.context.junit4.SpringRunner;
 9 import org.springframework.transaction.annotation.Transactional;
10 
11 import com.windy.mall.product.bean.Product;
12 import com.windy.mall.product.bean.TestBeanConfiguration;
13 
14 @RunWith(SpringRunner.class)
15 @SpringBootTest(classes=TestBeanConfiguration.class)
16 @Transactional
17 @Rollback(true)
18 public class ProductMapperTest {
19 
20     @Autowired
21     private ProductMapper mapper;
22     
23     @Autowired
24     private Product product;
25     
26     @Before
27     public void setUp(){
28         product.setPname("持續交付");
29         product.setType("書籍");
30         product.setPrice(69d);
31     }
32     
33     @Test
34     public void testAdd() {
35         Assert.assertEquals(Integer.valueOf(1), mapper.add(product));
36     }
37 
38 }
View Code

 

 

2. 針對Service層

因爲Service層須要調用Mapper層或者是Dao層,一般須要Mock Mapper對象.這裏須要使用到@MockBean註解,Mock Mapper層的行爲.

 1 package com.windy.mall.product.service;
 2 
 3 import org.junit.Assert;
 4 import org.junit.Before;
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.mockito.BDDMockito;
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.boot.test.context.SpringBootTest;
10 import org.springframework.boot.test.mock.mockito.MockBean;
11 import org.springframework.test.context.junit4.SpringRunner;
12 
13 import com.windy.mall.product.bean.Product;
14 import com.windy.mall.product.bean.TestBeanConfiguration;
15 import com.windy.mall.product.mapper.ProductMapper;
16 
17 @RunWith(SpringRunner.class)
18 @SpringBootTest(classes = TestBeanConfiguration.class)
19 public class ProductServiceTest {
20 
21     @MockBean
22     private ProductMapper mapper;
23 
24     @Autowired
25     private Product product;
26 
27     @Autowired
28     private ProductService service;
29 
30     @Before
31     public void setUp() {
32         BDDMockito.given(mapper.add(product)).willReturn(1);
33         BDDMockito.given(mapper.add(null)).willReturn(0);
34     }
35 
36     @Test
37     public void testAddService() {
38         Assert.assertEquals(Integer.valueOf(1), service.add(product));
39         Assert.assertEquals(Integer.valueOf(0), service.add(null));
40     }
41 
42 }
View Code

 

3.針對Controller

有兩種方法能夠作單元測試:

(1) 這裏須要用到web環境(webEnvironment=WebEnvironment.RANDOM_PORT).須要用到TestRestTemplate這個對象做爲客戶方,調用Controller(API)

 1 import org.junit.Assert;
 2 import org.junit.Test;
 3 import org.junit.runner.RunWith;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.boot.test.context.SpringBootTest;
 6 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
 7 import org.springframework.boot.test.web.client.TestRestTemplate;
 8 import org.springframework.test.context.junit4.SpringRunner;
 9 
10 @RunWith(SpringRunner.class)
11 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
12 public class ProductControllerTest {
13 
14     @Autowired
15     private TestRestTemplate template;
16     
17     @Test
18     public void test() {
19         String body = template.getForObject("/ms/product/1", String.class);
20         Assert.assertEquals("success", body);
21     }
22 
23 }
View Code

 

(2) 若是是使用MockMVC對象來測試,須要開啓@AutoConfigureMockMvc註解

 1 import org.junit.Test;
 2 import org.junit.runner.RunWith;
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 5 import org.springframework.boot.test.context.SpringBootTest;
 6 import org.springframework.test.context.junit4.SpringRunner;
 7 import org.springframework.test.web.servlet.MockMvc;
 8 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
 9 import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
10 
11 @RunWith(SpringRunner.class)
12 @SpringBootTest
13 @AutoConfigureMockMvc
14 public class ProductControllerTest2 {
15 
16     @Autowired
17     private MockMvc mvc;
18 
19     @Test
20     public void test() throws Exception {
21         mvc.perform(MockMvcRequestBuilders.get("/ms/product/1"))
22                 .andExpect(MockMvcResultMatchers.status().isOk())
23                 .andExpect(MockMvcResultMatchers.content().string("success"));
24     }
25 
26 }
View Code
相關文章
相關標籤/搜索