JUnit 单元测试入门
JUnit 入门
前言
- JUnit 测试代码的结构和生命周期
- JUnit 断言 Assertion API
- JUnit 是一个小儿简单的框架
A.1 基本的JUnit 测试类
- JUnit 测试类只是普通的java 类,包含一个或多个测试方法,以及零个或多个setup 和 teardown 方法
A.1.1 声明测试方法
-
最简单的形式是带有注解的普通实例方法
-
@Test public void thisIsATestMethod() { assertEquals(5,2+3); }
-
如果 JUnit 发现一个非public的方法,就会忽略他
-
如果 JUnit 发现方法带参数,就会忽略他
-
如果 JUnit 发现方法返回非 void ,就会忽略他
-
如果方法声明为 static ,就会忽略他
-
如果方法没有 JUnit 的 @Test 注解,就会忽略他
-
总结来看就是:测试方法必须是public void 的,并且不带参数的。
A.1.2 JUnit 测试的生命周期
- JUnit 扫描测试类中的各个方法,然后对满足上述约束条件的签名:
- 实例化测试类的一个实例
- 调用测试类方法的setup方法
- 调用测试类
- 调用测试类实例的 teardown 方法
A.1.3 测试的 setup 和 teardown
- @Before、@After 注解表示了 setup 方法和 teardown 方法,他确保测试在执行时可以设定为特定的条件,并且执行后再恢复到原来的条件
- 还有@BeforeClass 和 @AfterClass 注解,用来做类似的事情。
A.2 JUnit 断言
- JUnit 提供了一组常用的断言,他们是在org.junit.Assert 类中的
- 它们是public static 的方法
- 完整断言API
- 常用断言 API
- assertEquals:断言两个对象或者基本对象是否相等
- assertArrayEquals:断言两个数组是否包含相同的元素
- assertTrue:断言语句为真
- assertFalse:断言语句为假
- assertNull:断言对象引用为空
- assertNotNull:断言对象引用不为空
- assertSame:断言两个对象引用指向同一个实例
- assertNotSame:断言两个对象引用不指向同一个实例
- assertThat:断言对象满足指定条件
A.2.1 抛出断言异常
-
有时我们的代码行为就是在某些情况下抛出异常。例如,对于无效输入,你希望抛出IllegalArgumentException。如果你想要的行为就是异常,而Junit 将测试方法抛出异常理解为失败。
-
这种情况我们可以在测试方法内放置try-catch 来捕捉预期的异常,如果没有异常就令测试失败。
-
但 junit 提供给我们更方便的方法来做这件事。
-
@Test(expected = IllegalArgumentException.class) public void ensureThatInvalidPhoneNumberYieldsProperException() { FaxMachine fax = new FaxMachine(); fax.connect("not-a-phone-number"); //should throw an exception }
-
上例中我们使用@Test注解的expected 属性来声明我们期望在测试方法执行时抛出一个IllegalArgumentException 异常,如果没有抛出异常或者抛出其他异常,测试就会失败。
-
这是一个检查异常的简洁方式。
-
但有时我们想要更具体的了解抛出的是那种异常。例如,除了抛出的异常要符合某个类型之外,你还想检查其message 中携带的特殊信息,或者它封装了某种根因异常、这些情况下,我们就得回到古老却优秀的try-catch ,然后自行断言。
-
@Test public void ensureThatInvalidPhoneNumberYieldsProperException() { String invalidPhoneNumber = "not-a-phone-number"; FaxMachine fax = new FaxMachine(); try { fax.connect(invalidPhoneNumber); fail("should've raised an exception by now"); // 如果上面语句没有抛出异常跳转到catch 语句,则令测试失败。 } catch(IllegalArgumentException expected) { // 捕获期望的异常 assertThat(expected.getMessage(),containString(invalidPhoneNumber)); // 进一步对异常进行断言 } }
-
-
总结:如果只需要检查抛出异常的类型,则采用基于注解的方式把,这样既干净又简洁。
A.2.2 AssertThat()和 Hamcrest 匹配器
- 当内置的断言不能满足你的需求时,可以使用自定义匹配器扩展强大的assertThat()。