目錄
被測試類——獲取學生數據:
/** * 學生信息實體 */ public class EStudent{ String name; int age; // 一堆getter、setter /** * 注意:自定義類時要重寫equals方法,否則默認equals方法會使用==方式來比較對象的內存地址是否相同,而不是內容是否相同。 */ @Override public boolean equals(Object obj){ if (obj == null || obl.getClass() != this.getClass()) return false; EStudent other = (EStudent)obj; if (!this.getName().equals(other.getName()) || this.getAge() != other.getAge()) return false; return true; } } /** * 學生數據操作接口 */ public interface StudentDao{ public EStudent getStudent(int id); } /** * 真實的數據操作類 */ public class StudentDaoImpl implements StudentDao{ public EStudent getStudent(int id){ EStudent ret = new EStudent(); ret.setName("fsjohnhuang"); ret.setAge(18); return ret; } } /** * 模擬的數據操作類 */ public class MockStudentDaoImpl implements StudentDao{ public EStudent getStudent(int id){ EStudent ret = new EStudent(); ret.setName("fsjohnhuang"); ret.setAge(18); return ret; } }
測試用例:
/** * 由於下面采用參數化測試,因此將測試運行器更換為Parameterized */ @RunWith(Parameterized.class) public class TestStudentDao{ static StudentDao dao, mockDao; /** * 執行測試類中所有測試前執行一次 * 用於前提條件的初始化 */ @BeforeClass public static void init(){ dao = new StudentDaoImpl(); mockDao = new MockStudentDaoImpl(); } /** * 接收測試用數據 */ int id; public TestStudentDao(int id){ this.id = id; } /** * 測試用例 */ @Test public void testGetStudent(){ assertEquals("獲取學生信息", mockDao.getStudent(id), dao.getStudent(id)); } /** * 測試用數據提供方法 */ @Parameters public Collection dataFeed(){ return Arrays.asList(new Object[][]{{1},{2},{3}}); } }
第一次接觸時可能不能理解上面的代碼片段到底發生了什么事,ctrl+c到eclipse那執行一下吧!下面我們詳細了解JUnit4吧!
就是每個測試方法執行前和后都執行的方法,用於自動初始化和回收資源等工作。通過 @Before 注解標注測試方法執行前調用的固件測試,通過 @After 注解標注測試方法執行后調用的固件測試。
父類的固件測試會在子類的固件測試前被調用。
另外可通過注解 @BeforeClass 和 @AfterClass 標注某些static方法為測試開始前和結束后被調用,用於自動初始化和回收資源等工作。注意通過注解 @BeforeClass 和 @AfterClass 標注的方法一次測試過程僅被調用一次而已。示例如下:
public class MyUT{ int i, j; @BeforeClass public void static init(){ System.out.println("init"); i = 0; j = 0; } @Before public void invokeBefore(){ System.out.println("invokeBefore" + ++i); } @Test public void testMyMethod1(){ System.out.println("testMyMethod1"); } @Test public void testMyMethod2(){ System.out.println("testMyMethod2"); } @After public void invokeAfter(){ System.out.println("invokeAfter" + ++j); } @AfterClass public void static destroy(){ System.out.println("destroy"); i = 0; j = 0; } } // 輸出結果 init invokeBefore1 testMyMethod1 invokeAfter1 invokeBefore2 testMyMethod2 invokeAfter2 destroy
通過注解 @Ignore() 可以標注不參與測試的測試方法。當然也可以通過去除注解 @Test 來達到這個目的,但去除注解 @Test 會令到eclipse的JUnit View中無法顯示該測試方法。
通過注解 @Test(expected=Class類型) 來標注期待測試方法執行時拋出哪種異常對象,若測試方法不拋出異常或異常對象與期待的異常對象不相同則測試失敗。
@Test(expected=ArithmeticException.class) public void calc(){ int i = 1/0; }
通過注解 @Test(timeout=毫秒數) 來標注期待執行測試方法的最大耗時,若超時則測試失敗。
@Test(timeout=1000) public void wait(){ while(true){} }
用於執行JUnit中所有的測試方法。JUnit為單元測試提供默認的測試運行器,但我們可以自定義,自定義的測試運行器必須繼承 org.junit.runner.Runner 。然后通過類注解 @RunWith(CustomTestRunner.class) 來指定該測試的測試運行器。
常用的內置測試運行器:
1. org.junit.runners.Suite ,套件測試時使用。
2. org.junit.runners.Parameterized ,參數化測試時使用。
就是第一節中的測試類型,用於模擬以不同的參數組合來對方法進行多次測試。若不使用參數化測試,該測試方法有N個不同的參數組合,則需要寫N個測試方法來測試。
// 需要使用Parameterized測試運行器才可以 @RunWith(Parameterized.class) public class MyUT{ // 成員變量,用於存放測試用數據和測試期望值 int orig; int expected; public MyUT(int orig, int expected){ this.orig = orig; this.expected = expected; } @Test public void testMyMethod(){ assertEquals(expected, orig + 1); } /** * 測試數據和測試期望值的提供方法 * 必須用注解@Parameters標注 * 必須返回Collection類型數據 */ @Parameters public Collection dataFeed(){ return Arrays.asList(new Object[][]{ {1, 2}, {2, 3}, {3, 4} }); } }
JUnit4去除JUnit3中套件測試注解,而是通過另一形式提供套件測試。
套件測試就是按業務邏輯將測試類進行分組,並以組為單位執行單元測試。
// 測試類1 public class MyUT1{ @Test public void testMyMehthod1(){ assertEquals(1,1); } } // 測試類2 public class MyUT2{ @Test public void testMyMehthod2(){ assertEquals(2,2); } } // 套件測試類 @RunWith(Suite.class) @SuiteClass({MyUT1.class, MyUT2.class}) public class SuiteTest{ // 必須有一個public,無參數的構造函數。使用默認的構造函數也可以 public SuiteTest(){} }
JUnit4.4內置Hamcrest測試組件的部分內容,而 assertThat斷言 就是配置Hamcrest測試組件的匹配符來實現所有測試工作。由於Hamcrest的匹配符貼近自然語言,因此意思表達更明確。(JUnit4.4前的版本則需要引入hamcrest-core.jar和hamcrest-library.jar了)。
/* assertThat語法 * assertThat(T actual, Matcher<T> matcher); * assertThat(String reason, T actual, Matcher<T> matcher); * 入參actual為實際值,入參matcher為期待值的匹配符 */ //測試變量是否大於指定值 assertThat(1, greaterThan(50)); //測試變量是否小於指定值 assertThat(1, lessThan(100)); //測試變量是否大於等於指定值 assertThat(1, greaterThanOrEqualTo(50)); //測試變量是否小於等於指定值 assertThat(1, lessThanOrEqualTo(100)); //測試所有條件必須成立 assertThat(1, allOf(greaterThan(50),lessThan(100))); //測試只要有一個條件成立 assertThat(1, anyOf(greaterThanOrEqualTo(50), lessThanOrEqualTo(100))); //測試無論什么條件成立(還沒明白這個到底是什么意思) assertThat(1, anything()); //測試變量值等於指定值 assertThat(1, is(100)); //測試變量不等於指定值 assertThat(1, not(50)); /**字符串**/ String url = "http://www.taobao.com"; //測試變量是否包含指定字符 assertThat(url, containsString("taobao")); //測試變量是否已指定字符串開頭 assertThat(url, startsWith("http://")); //測試變量是否以指定字符串結尾 assertThat(url, endsWith(".com")); //測試變量是否等於指定字符串 assertThat(url, equalTo("http://www.taobao.com")); //測試變量再忽略大小寫的情況下是否等於指定字符串 assertThat(url, equalToIgnoringCase("http://www.taobao.com")); //測試變量再忽略頭尾任意空格的情況下是否等於指定字符串 assertThat(url, equalToIgnoringWhiteSpace("http://www.taobao.com")); /**集合**/ List<User> user = new ArrayList<User>(); user.add(test1); user.add(test2); //測試集合中是否還有指定元素 assertThat(user, hasItem(test1)); assertThat(user, hasItem(test2)); /**Map匹配**/ Map<String,User> userMap = new HashMap<String,User>(); userMap.put(test1.getUsername(), test1); userMap.put(test2.getUsername(), test2); //測試map中是否還有指定鍵值對 assertThat(userMap, hasEntry(test1.getUsername(), test1)); //測試map中是否還有指定鍵 assertThat(userMap, hasKey(test2.getUsername())); //測試map中是否還有指定值 assertThat(userMap, hasValue(test2));
位於 org.junit.Assume類 下,同樣是屬於Hamcrest組件的。用於假設當條件成立時才會執行后續的代碼,條件不成立時是不會影響測試結果。
assumeThat(1, is(0)); System.out.println("I'm here"); // 這句不會被執
尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/4061902.html ^_^肥仔John
http://blog.csdn.net/skyie53101517/article/details/8739126