SpringBoot重點詳解--使用Junit進行單元測試


目錄

添加依賴與配置

ApplicationContext測試

Environment測試

MockBean測試

Controller測試

情況一

情況二

方法一

方法二


本文將對在Springboot中如何使用Junit進行單元測試進行簡單示例和介紹,項目的完整目錄層次如下圖所示。 

添加依賴與配置

為了保證測試的完整性,本工程POM文件中除引入Junit單元測試依賴外,還額外引入了用來測試JDBC和Controller的JPA和WEB依賴。 


   
   
  
  
          
  1. <parent>
  2. <groupId>org.springframework.boot </groupId>
  3. <artifactId>spring-boot-starter-parent </artifactId>
  4. <version>1.5.6.RELEASE </version>
  5. </parent>
  6. <dependencies>
  7. <!-- 添加MySQL依賴 -->
  8. <dependency>
  9. <groupId>mysql </groupId>
  10. <artifactId>mysql-connector-java </artifactId>
  11. </dependency>
  12. <!-- 添加JDBC依賴 -->
  13. <dependency>
  14. <groupId>org.springframework.boot </groupId>
  15. <artifactId>spring-boot-starter-data-jpa </artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.boot </groupId>
  19. <artifactId>spring-boot-starter-web </artifactId>
  20. </dependency>
  21. <!-- 引入單元測試依賴 -->
  22. <dependency>
  23. <groupId>org.springframework.boot </groupId>
  24. <artifactId>spring-boot-starter-test </artifactId>
  25. <scope>test </scope>
  26. </dependency>
  27. </dependencies>

同時,在src/main/resources目錄下添加核心配置文件application.properties,內容如下。  


   
   
  
  
          
  1. #########################################################
  2. ### Spring DataSource -- DataSource configuration ###
  3. #########################################################
  4. spring.datasource.url=jdbc:mysql://localhost:3306/dev1?useUnicode=true&characterEncoding=utf8
  5. spring.datasource.driverClassName=com.mysql.jdbc.Driver
  6. spring.datasource.username=root
  7. spring.datasource.password=123456
  8. #########################################################
  9. ### Java Persistence Api -- Spring jpa configuration ###
  10. #########################################################
  11. # Specify the DBMS
  12. spring.jpa.database = MYSQL
  13. # Show or not log for each sql query
  14. spring.jpa.show- sql = true
  15. # Hibernate ddl auto ( create, create- drop, update)
  16. spring.jpa.hibernate.ddl- auto = update
  17. # Naming strategy
  18. #[org.hibernate.cfg.ImprovedNamingStrategy #org.hibernate.cfg.DefaultNamingStrategy]
  19. spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
  20. # stripped before adding them to the entity manager)
  21. spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

ApplicationContext測試

在Springboot中使用Junit進行單元測試的方法很簡單,只需要在編寫的單元測試類上添加兩個注解:@RunWith(SpringRunner.class)和@SpringBootTest。 


   
   
  
  
          
  1. @RunWith(SpringRunner.class) // 等價於使用 @RunWith(SpringJUnit4ClassRunner.class)
  2. @SpringBootTest(classes = { MyApplication.class, TestConfig.class })
  3. public class ApplicationContextTest {
  4. @Autowired
  5. private ApplicationContext context;
  6. @Autowired
  7. private UserDao userDao;
  8. @Test
  9. public void testUserDao() {
  10. userDao.addUser( 18, "pengjunlee");
  11. }
  12. @Test
  13. public void testConfiguration() {
  14. Runnable bean = context.getBean(Runnable.class);
  15. Assert.assertNotNull(bean);
  16. bean.run();
  17. }
  18. }

UserDao定義如下。  


   
   
  
  
          
  1. @Repository
  2. public class UserDao {
  3. @Autowired
  4. private JdbcTemplate jdbcTemplate;
  5. @Transactional
  6. public void addUser(Integer userAge, String userName) {
  7. String sql = "insert into tbl_user (age,name) values ('" + userAge + "','" + userName + "');";
  8. jdbcTemplate.execute(sql);
  9. }
  10. }

TestConfig定義如下。 


   
   
  
  
          
  1. /**
  2. * @TestConfiguration注解的配置內的Bean僅在測試時裝配
  3. */
  4. @TestConfiguration
  5. public class TestConfig {
  6. @Bean
  7. public Runnable createRunnable(){
  8. return ()->{
  9. System.out.println( "This is a test Runnable bean...");
  10. };
  11. }
  12. }

提示:@SpringBootTest注解的classes可以指定用來加載Spring容器所使用的配置類,@TestConfiguration注解修飾的配置類內的Bean僅在測試的時候才會裝配。  

Environment測試

我們可以通過@SpringBootTest注解的properties屬性向Environment中設置新的屬性,也可以通過使用EnvironmentTestUtils工具類來向ConfigurableEnvironment中添加新的屬性。 


   
   
  
  
          
  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(properties = { "app.token=pengjunlee" })
  3. public class EnvironmentTest {
  4. @Autowired
  5. private Environment env;
  6. @Autowired
  7. private ConfigurableEnvironment cenv;
  8. @Before
  9. public void init() {
  10. EnvironmentTestUtils.addEnvironment(cenv, "app.secret=55a4b77eda");
  11. }
  12. @Test
  13. public void testEnvironment() {
  14. System.out.println(env.getProperty( "spring.datasource.url"));
  15. Assert.assertEquals( "pengjunlee", env.getProperty( "app.token"));
  16. Assert.assertEquals( "55a4b77eda", cenv.getProperty( "app.secret"));
  17. }
  18. @Test
  19. @Ignore // 忽略測試方法
  20. public void testIgnore() {
  21. System.out.println( "你看不見我...");
  22. }
  23. }

擴展:Junit測試用例執行順序:@BeforeClass ==> @Before ==> @Test ==> @After ==> @AfterClass 。

注意:在使用Junit對Spring容器進行單元測試時,若在src/test/resources 目錄下存在核心配置文件,Spring容器將會只加載src/test/resources 目錄下的核心配置文件,而不再加載src/main/resources 目錄下的核心配置文件。  

MockBean測試

我們可以通過@MockBean注解來對那些未添加實現的接口進行模擬測試,預先設定好調用方法期待的返回值,然后再進行測試。

例如,有如下的IUserService接口,定義了一個getUserAge()方法用來根據用戶的ID來查詢用戶的年齡。 


   
   
  
  
          
  1. public interface IUserService {
  2. Integer getUserAge(Long userId);
  3. }

使用@MockBean來對IUserService接口進行模擬測試,測試代碼如下。  


   
   
  
  
          
  1. @RunWith(SpringRunner.class)
  2. public class MockBeanTest {
  3. @MockBean
  4. private IUserService userService;
  5. @SuppressWarnings( "unchecked")
  6. @Test(expected = NullPointerException.class)
  7. public void testMockBean() {
  8. BDDMockito.given(userService.getUserAge( 2L)).willReturn(Integer.valueOf( 18));
  9. BDDMockito.given(userService.getUserAge( 0L)).willReturn(Integer.valueOf( 0));
  10. BDDMockito.given(userService.getUserAge( null)).willThrow(NullPointerException.class);
  11. Assert.assertEquals(Integer.valueOf( 18), userService.getUserAge( 2L));
  12. Assert.assertEquals(Integer.valueOf( 0), userService.getUserAge( 0L));
  13. Assert.assertEquals(Integer.valueOf( 0), userService.getUserAge( null));
  14. }
  15. }

Controller測試

在Springboot中可以通過TestRestTemplate和MockMvc來對Controller進行測試,有以下兩種情況。

情況一

Controller中未裝配任何其他Spring容器中的Bean,例如下面這個控制器。 


   
   
  
  
          
  1. @RestController
  2. @RequestMapping( "/user")
  3. public class UserController01 {
  4. @GetMapping( "/home")
  5. public String homeUser(@RequestParam(name = "name", required = true) String userName) {
  6. if ( null == userName || userName.trim() == "") {
  7. return "you are nobody...";
  8. }
  9. return "This is " + userName + "'s home...";
  10. }
  11. }

此時無需啟動Spring容器,可直接使用MockMvc來對Controller進行模擬測試,測試代碼如下。  


   
   
  
  
          
  1. @RunWith(SpringRunner.class)
  2. @WebMvcTest(controllers = { UserController01.class })
  3. public class ControllerTest01 {
  4. @Autowired
  5. private MockMvc mvc;
  6. @Test
  7. public void testAddUser() throws Exception {
  8. mvc.perform(MockMvcRequestBuilders.get( "/user/home").param( "name", ""))
  9. .andExpect(MockMvcResultMatchers.status().isOk())
  10. .andExpect(MockMvcResultMatchers.content().string( "you are nobody..."));
  11. mvc.perform(MockMvcRequestBuilders.get( "/user/home").param( "name", "pengjunlee"))
  12. .andExpect(MockMvcResultMatchers.status().isOk())
  13. .andExpect(MockMvcResultMatchers.content().string( "This is pengjunlee's home..."));
  14. }
  15. }

情況二

Controller中需裝配其他Spring容器中的Bean,例如下面這個控制器。 


   
   
  
  
          
  1. @RestController
  2. @RequestMapping( "/user")
  3. public class UserController02 {
  4. @Autowired
  5. private UserDao userDao;
  6. @GetMapping( "/add")
  7. public String addUser(@RequestParam(name = "age", required = false, defaultValue = "0") Integer userAge,
  8. @RequestParam(name = "name", required = true) String userName) {
  9. if (userAge <= 0 || null == userName || userName.trim() == "") {
  10. return "0";
  11. }
  12. userDao.addUser(userAge, userName);
  13. return "1";
  14. }
  15. }

此時除了要啟動Spring容器,還需要啟動內嵌的WEB環境,有以下兩種方法。

方法一

利用TestRestTemplate進行測試。 


   
   
  
  
          
  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
  3. public class ControllerTest02 {
  4. @Autowired
  5. private TestRestTemplate template;
  6. @Test
  7. public void testAddUser() {
  8. String result1 = template.getForObject( "/user/add?name=pengjunlee", String.class);
  9. Assert.assertEquals( "0", result1);
  10. String result2 = template.getForObject( "/user/add?age=20&name=Tracy", String.class);
  11. Assert.assertEquals( "1", result2);
  12. }
  13. }

方法二

利用MockMvc進行測試。 


   
   
  
  
          
  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
  3. @AutoConfigureMockMvc
  4. public class ControllerTest03 {
  5. @Autowired
  6. private MockMvc mvc;
  7. @Test
  8. public void testAddUser() throws Exception {
  9. mvc.perform(MockMvcRequestBuilders.get( "/user/add").param( "name", ""))
  10. .andExpect(MockMvcResultMatchers.status().isOk())
  11. .andExpect(MockMvcResultMatchers.content().string( "0"));
  12. mvc.perform(MockMvcRequestBuilders.get( "/user/add").param( "age", "22").param( "name", "pengjunlee"))
  13. .andExpect(MockMvcResultMatchers.status().isOk())
  14. .andExpect(MockMvcResultMatchers.content().string( "1"));
  15. }
  16. }

本文項目源碼已上傳至CSDN,資源地址:https://download.csdn.net/download/pengjunlee/10394302  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM