SpringBoot(20)---斷言(Assert)


SpringBoot(20)---斷言(Assert)

我們在寫單元測試的時候,除了接口直接拋異常而導致該單元測試失敗外,還有種是業務上的錯誤也代表着該單元測試失敗。好比我們在測試接口的時候,

該接口返回是1代表成功,如果是0那就代表是失敗的,這個時候可以考慮使用斷言。

一、原理

我們知道,我們可以通過斷言來校驗測試用例的返回值和實際期望值進行比較,以此來判斷測試是否通過。那我們先來看下如果失敗的情況下它的流程是怎么樣的。

對於斷言而言,如果是錯誤最終都會進入下面的方法

    static public void fail(String message) {
        if (message == null) {
            throw new AssertionError();
        }
        throw new AssertionError(message);
    }

很明顯,這里有一個AssertionError對象,我們來看下這個對象。

public class AssertionError extends Error {
 //......
}

我們很明顯看到,它實繼承是Error,而不是Exception。這說明什么,說明你無法通過try catch去捕獲這個異常,只要進入斷言fail中,一定會拋出異常。


二、Assert 源碼

這里只展示Assert源碼中常用的方法,一些不常用或者過期的方法這里就不展示了。

public class Assert {
    /**
     * 結果 = 預期 則正確
     */
    static public void assertEquals(Object expected, Object actual)
    /**
     * 結果 != 預期 則正確
     */
    static public void assertNotEquals(Object unexpected, Object actual)
    /**
     * condition == true 則正確
     */
    static public void assertTrue(boolean condition)
    /**
     * condition == false 則正確
     */
    static public void assertFalse(boolean condition)
    /**
     * 永遠是錯誤
     */
    static public void fail()
    /**
     * 結果不為空 則正確
     */
    static public void assertNotNull(Object object)
    /**
     * 結果為空 則正確
     */
    static public void assertNull(Object object)
    /**
     * 兩個對象引用 相等 則正確(上面相當於equels 這里類似於使用“==”比較兩個對象)
     */
    static public void assertSame(Object expected, Object actual)
    /**
     * 兩個對象引用 不相等 則正確
     */
    static public void assertNotSame(Object unexpected, Object actual)
    /**
     * 兩個數組相等 則正確
     */
    public static void assertArrayEquals(Object[] expecteds, Object[] actuals)
    /**
     * 這個單獨介紹
     */
    public static <T> void assertThat(T actual, Matcher<? super T> matcher)  
}

注意 上面每一個方法,都會有一個多一個參數的方法,這個參數為:String message。意思就是錯誤的情況下,我們可以輸出我們自定義的message

示例

   //這個就表示 結果 != 預期 的情況下,拋出的AssertionError 信息是我們指定的message
   static public void assertEquals(String message,Object expected, Object actual)

上面還有一個方法需要單獨介紹,那就是assertThat方法。


三、assertThat方法

大家習慣把assertThat理解成新斷言,因為上面所以的功能方法,都可以通過assertThat這一個方法來實現。

1、基本語法

assertThat 的基本語法如下:

assertThat( [value], [matcher statement] );

value 是接口返回信息中,我們想要測試的變量值

matcher statement: 是使用Hamcrest匹配符來表達的對前面變量所期望的值的聲明,如果value值與matcher statement所表達的期望值相符,則測試成功,否則測試失敗。

2、基本使用

字符串匹配符

  String n = "xiao";
// containsString:字符串變量中包含指定字符串時,測試通過
assertThat(n, containsString("xiao"));
// startsWith:字符串變量以指定字符串開頭時,測試通過
assertThat(n, startsWith("xi"));
// endsWith:字符串變量以指定字符串結尾時,測試通過
assertThat(n, endsWith("ao"));
// euqalTo:字符串變量等於指定字符串時,測試通過
assertThat(n, equalTo("xiao"));
// equalToIgnoringCase:字符串變量在忽略大小寫的情況下等於指定字符串時,測試通過
assertThat(n, equalToIgnoringCase("xiao"));
// equalToIgnoringWhiteSpace:字符串變量在忽略頭尾任意空格的情況下等於指定字符串時,測試通過
assertThat(n, equalToIgnoringWhiteSpace(" xiao   "));

int匹配符

int s = 1;
// allOf:所有條件必須都成立,測試才通過(大於1同時小於3)
assertThat(s, allOf(greaterThan(1), lessThan(3)));
// anyOf:只要有一個條件成立,測試就通過 (大於1或者小於2)
assertThat(s, anyOf(greaterThan(1), lessThan(2)));
// anything:無論什么條件,測試都通過
assertThat(s, anything());
// is:變量的值等於指定值時,測試通過
assertThat(s, is(2));
// not:和is相反,變量的值不等於指定值時,測試通過
assertThat(s, not(1));

double匹配符

double d = 1D;
// closeTo:浮點型變量的值在3.0±0.5范圍內,測試通過
assertThat(d, closeTo(3.0, 0.5));
// greaterThan:變量的值大於指定值時,測試通過
assertThat(d, greaterThan(3.0));
// lessThan:變量的值小於指定值時,測試通過
assertThat(d, lessThan(3.5));
// greaterThanOrEuqalTo:變量的值大於等於指定值時,測試通過
assertThat(d, greaterThanOrEqualTo(3.3));
// lessThanOrEqualTo:變量的值小於等於指定值時,測試通過
assertThat(d, lessThanOrEqualTo(3.4));

集合匹配符

List<String> list = new ArrayList();
// hasItem:Iterable變量中含有指定元素時,測試通過
assertThat(list, hasItem("xiao"));
Map<String, String> m = new HashMap<>();
// hasEntry:Map變量中含有指定鍵值對時,測試通過
assertThat(m, hasEntry("xi", "xiao"));
// hasKey:Map變量中含有指定key時,測試通過
assertThat(m, hasKey("x"));
// hasValue:Map變量中含有指定value值時,測試通過
assertThat(m, hasValue("x"));

四、測試

這里對於老斷言,和新斷言各測試5個。

1、老斷言

示例

public class TestServiceImplTest {
 
    @Test
    public void test1() {
        String str = "xiao";
        assertEquals(str, "xiaoniao");//不相等,所以錯誤
    }
    @Test
    public void test2() {
        assertFalse(Boolean.TRUE); //不是false,所以錯誤
    }
    @Test
    public void test3() {
       fail("直接是錯誤"); //直接是錯誤
    }
    @Test
    public void test4() {
        assertNull("xiao"); //不為空所以為錯誤
    }
    @Test
    public void test5() {
        assertNotNull("xiao");//不為空,所以為正確
    }
}

這里應該只有第5個測試用例通過,前面4個都不通過的,我們在來看實際運行結果

與實際相符,前面4個,測試用例不通過。而且可以看到第3個是我們自定義錯誤信息,在控制台也打印出來了。

2、新斷言

示例

import org.assertj.core.util.Lists;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

public class TestServiceImplTest {

    @Test
    public void test1() {
        String str = "xiao";
        assertThat("這兩字符串不相等",str, is("xiaoniao"));//不相等,所以錯誤
    }
    @Test
    public void test2() {
        int s = 1;
        assertThat(s, anyOf(greaterThan(1), lessThan(2)));//滿足 大於1或者小於2 所以正確
    }
    @Test
    public void test3() {
        double d = 1D;
        assertThat(d, allOf(greaterThanOrEqualTo(1D),lessThan(2D)));//滿足大於等於1 並且 小於2 所以正確
    }
    @Test
    public void test4() {
        List<String> list = Lists.newArrayList("xiao","zhong","da");
        assertThat(list, hasItem("xiao"));  //包含xiao 所以正確
    }
    @Test
    public void test5() {
        Map<String, String> map = new HashMap<>();
        map.put("xiao", "xiao");
        assertThat(map, hasKey("xiao")); //該map包含該key,所以正確
    }
}

這里應該只有第1個測試用例不通過,其它都是通過的,我們在來看實際運行結果

符合預期。

好了,整篇文章到這里就結束了,下面把該項目的具體代碼放到github上。

GitHub地址 :07-test



別人罵我胖,我會生氣,因為我心里承認了我胖。別人說我矮,我就會覺得好笑,因為我心里知道我不可能矮。這就是我們為什么會對別人的攻擊生氣。
攻我盾者,乃我內心之矛(31)


免責聲明!

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



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