idea spring boot 1.x junit單元測試


  目前最主流的單元測試框架是junit,其中spring boot 1.x系列主要使用junit 4,spring boot 2.x主要使用junit 5;mock類和打樁的主要框架是mockito,主要有1.x(spring boot 1.x依賴),2.x(spring boot 2.0, 2.1依賴),3.x(spring boot 2.2依賴)三個版本。

0、關於單元測試首先需要理解的是的,單元測試不能代替接口測試,前者是開發的事情,后者是開發為輔、測試為主。其目的是為了驗證某個方法自身的邏輯沒有問題、而沒有職責驗證其依賴的服務是否存在問題。因此,單元測試應該是很輕量的,甚至都不應該依賴spring環境,不需要啟動servlet容器,否則就成了自動化半集成測試,所以簡單的增刪改查不適合作為單元測試的對象。

1、參考https://www.cnblogs.com/Maoscn/p/10313660.html,安裝Junit4插件。

2、復習下junit中的注解。

@BeforeClass:針對所有測試,只執行一次,且必須為static void
@Before:初始化方法,執行當前測試類的每個測試方法前執行。

@SpringBootTest:獲取啟動類、加載配置,確定裝載Spring Boot,如果找不到@SpringBootConfiguration啟動類將運行出錯;

@Test:測試方法,在這里可以測試期望異常和超時時間
@After:釋放資源,執行當前測試類的每個測試方法后執行
@AfterClass:針對所有測試,只執行一次,且必須為static void
@Ignore:忽略的測試方法(只在測試類的時候生效,單獨執行該測試方法無效)
@RunWith:標識為JUnit的運行環境 ,缺省值 org.junit.runner.Runner,也可以是JUnit4.class。

一個單元測試類執行順序為:

@BeforeClass –> @Before –> @Test –> @After –> @AfterClass

每一個測試方法的調用順序為:

@Before –> @Test –> @After

斷言測試

斷言測試也就是期望值測試,是單元測試的核心之一也就是決定測試結果的表達式,Assert對象中的斷言方法:

  • Assert.assertEquals 對比兩個值相等
  • Assert.assertNotEquals 對比兩個值不相等
  • Assert.assertSame 對比兩個對象的引用相等
  • Assert.assertArrayEquals 對比兩個數組相等
  • Assert.assertTrue 驗證返回是否為真
  • Assert.assertFlase 驗證返回是否為假
  • Assert.assertNull 驗證null
  • Assert.assertNotNull 驗證非null

除了常規的測試外,JUnit還通過其它特性的測試。

超時測試
如果一個測試用例比起指定的毫秒數花費了更多的時間,那么 Junit 將自動將它標記為失敗。timeout 參數和 @Test注釋一起使用。現在讓我們看看活動中的 @test(timeout)。

@Test(timeout = 1000)
public void testTimeout() throws InterruptedException {
    TimeUnit.SECONDS.sleep(2);
    System.out.println("Complete");
}

上面測試會失敗,在一秒后會拋出異常 org.junit.runners.model.TestTimedOutException: test timed out after 1000 milliseconds

異常測試
你可以測試代碼是否它拋出了想要得到的異常。expected 參數和 @Test 注釋一起使用。現在讓我們看看活動中的 @Test(expected)。

@Test(expected = NullPointerException.class)
public void testNullException() {
    throw new NullPointerException();
}

上面代碼會測試成功。

套件測試

public class TaskOneTest {
    @Test
    public void test() {
        System.out.println("Task one do.");
    }
}

public class TaskTwoTest {
    @Test
    public void test() {
        System.out.println("Task two do.");
    }
}

public class TaskThreeTest {
    @Test
    public void test() {
        System.out.println("Task Three.");
    }
}

@RunWith(Suite.class) // 1. 更改測試運行方式為 Suite
// 2. 將測試類傳入進來
@Suite.SuiteClasses({TaskOneTest.class, TaskTwoTest.class, TaskThreeTest.class})
public class SuitTest {
    /**
     * 測試套件的入口類只是組織測試類一起進行測試,無任何測試方法,
     */
}

3、Spring Boot 中使用 JUnit

Spring 框架提供了一個專門的測試模塊(spring-test),用於應用程序的集成測試。 在 Spring Boot 中,你可以通過spring-boot-starter-test啟動器快速開啟和使用它,其中包含了junit、hamcrest、mockito及asset相關類。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
// 獲取啟動類,加載配置,確定裝載 Spring 程序的裝載方法,它回去尋找 主配置啟動類(被 @SpringBootApplication 注解的)
@SpringBootTest
// 讓 JUnit 運行 Spring 的測試環境, 獲得 Spring 環境的上下文的支持
@RunWith(SpringRunner.class)
public class EmployeeServiceImplTest {
    // do 
}

  在微服務架構中,一般來說前后端是分離的,后端一般controller層會極其弱化,或者rpc服務自動暴露為REST API接口。所以webmvc層的單元測試在設計合理的架構中是不必要的,雖然Spring Boot Test提供了相當完備的功能供單元測試(具體可見https://blog.csdn.net/qq_35915384/article/details/80227297的前半部分。),但是在微服務架構中,它太重了。在一個典型的服務中,它的調用是這樣的:

 

   為了測試A類,必須把B-E類全部服務都構建好,如果其中有其它微服務提供的接口,則不得不依賴擋板或集成測試環境,這樣測試成本就會很高。所以,更好的做法是為B、C做mock類(對於每個被測類來說,Mock是類級別的,跟分支數無關),為B、C類的方法做stub(stub是根據B/C類對應方法有多少不同出入參對來決定的,一一對應。注:單元測試幾乎所有被測類依賴的有狀態類都需要Mock,接口測試則只需要Mock其他微服務的接口),這樣就可以不用依賴spring環境完成測試。如下:

  

  但是事情通常要比這更復雜,有些非業務服務類可能需要依賴spring的配置信息,有一些利用了spring ioc的各種特性比如ApplicationContext.getBean()、多數據源切換、AOP攔截器、復雜邏輯生成文件等,對於這些特殊場景,仍然是需要仔細設計單元測試。正常情況下單元測試僅僅是為了測試邏輯,通常不包括事務,否則清理和准備通常也要花費不低的成本。如果一定要測試數據庫,在單元測試上方法上增加@Transactional(加上會使得最后所有事務被回滾)注解反而不一定合適了,因為既然要測試數據庫,則起碼ACID應該測試。

  其次,對於樁而言,通常都是為了返回某個結果,對於一些包含很多字段的pojo和List,每次造這些數據也是比較耗時的,因此建議在json文件中維護相關的dto和pojo實例化數據及其配套工具類,進行統一的注入,這樣單元測試的重復代碼就可以大大減少。

       對於一個方法來說,單元測試的最低要求是100%的代碼覆蓋率,至少已知的通過、不通過、拋出的Exception得測到。除了簡單的業務查詢外,幾乎不可能只有一個test case,如果一個方法只有一個單元測試,幾乎可以肯定單元測試是為了應付,所以對每個方法,在javadoc上維護好場景清單,至少應包括:場景說明,入參(線程上下文變量),返回值/XXXException很重要,只有這樣單測才會有效果。

4、要實踐好單元測試,首先得掌握事半功倍的技巧,不然很容易事倍功半,對單元測試總結得最好的一篇文章之一可以參見https://www.jianshu.com/p/afb04b925db3、https://www.jdon.com/53146也可以參考。

 


免責聲明!

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



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