Junit4
Junit是Java中用于测试的一个单元库,其包含以下几项重要功能:
@Test注解驱动测试
public class RegularExpressionJUnit4Test {
private static String zipRegEx = "^\\d{5}([\\-]\\d{4})?$";
private static Pattern pattern;
@Test
public void verifyZipCodeNoMatch() throws Exception{
Matcher mtcher = this.pattern.matcher("2211");
boolean notValid = mtcher.matches();
assertFalse("Pattern did validate zip code", notValid);
}
}
Junit4的异常测试
设置@Test的 expected 、timeout等参数来测试异常和超时。
@Test(expected=IndexOutOfBoundsException.class)
public void verifyZipCodeGroupException() throws Exception{
Matcher mtcher = this.pattern.matcher("22101-5051");
boolean isValid = mtcher.matches();
mtcher.group(2);
}
@Test(timeout=1)
public void verifyFastZipCodeMatch() throws Exception{
Pattern pattern = Pattern.compile("^\\d{5}([\\-]\\d{4})?$");
Matcher mtcher = pattern.matcher("22011");
boolean isValid = mtcher.matches();
assertTrue("Pattern did not validate zip code", isValid);
}
Junit4忽略测试
忽略坏掉或不完整的测试,可以通过添加@Ignore注解来实现。
@Ignore("this regular expression isn't working yet")
@Test
public void verifyZipCodeMatch() throws Exception{
Pattern pattern = Pattern.compile("^\\d{5}([\\-]\\d{4})");
Matcher mtcher = pattern.matcher("22011");
boolean isValid = mtcher.matches();
assertTrue("Pattern did not validate zip code", isValid);
}
Junit4测试固件
固件是测试前和测试后必须执行的操作,通过注解@BeforeClass、@AfterClass、@Before、@After来实现。在类层次,有 @BeforeClass 和 @AfterClass,在方法(或测试)层次,有 @Before 和 @After。
@Before
public static void setUpBeforeClass() throws Exception {
pattern = Pattern.compile(zipRegEx);
}
@Test
public void verifyZipCodeNoMatch() throws Exception{
Matcher mtcher = this.pattern.matcher("2211");
boolean notValid = mtcher.matches();
assertFalse("Pattern did validate zip code", notValid);
}
Junit4套件测试
捆绑多个测试类,进行以组为单位的测试。使用@Runwith和@SuiteClasses注解来实现:
@RunWith(Suite.class)
@SuiteClasses({ParametricRegularExpressionTest.class,
RegularExpressionTest.class,
TimedRegularExpressionTest.class})
public class JUnit4Suite {}
Junit4参数测试
偶尔,应用程序的业务逻辑要求您编写许多不定量的测试来保证其健壮。在 JUnit 之前的版本中,这种场景很不方便,主要是因为一个测试中方法的参数组各不相同,意味着要为每一个单独的组编写一个测试用例。
详情参照博客:https://www.ibm.com/developerworks/cn/education/java/j-junit4/index.html
EasyMock
EasyMock 是一个针对 Java 编程语言的开放源码 mock 对象库,可以帮助您快速轻松地创建用于这些用途的 mock 对象。EasyMock 使用动态代理,让您只用一行代码就能够创建任何接口的基本实现。
mock 对象有助于从测试中消除依赖项。它们使测试更单元化。涉及 mock 对象的测试中的失败很可能是要测试的方法中的失败,不太可能是依赖项中的问题。这有助于隔离问题和简化调试。
添加依赖:
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.0</version>
</dependency>
创建mock对象——EasyMock.createMock(myInterface.class)
假设我们有一个这样一个接口:
import java.io.IOException;
public interface ExchangeRate {
double getRate(String inputCurrency, String outputCurrency) throws IOException;
}
现在我们另一个类的测试依赖于这个接口,它需要一个该接口的实现才能继续测试。这时,我们不需要真的创建一个该接口的实现类,并且实例化它。我们只需要用Mock创建一个ExchangeRate接口的模拟实现即可,简单快捷:
ExchangeRate mock = EasyMock.createMock(ExchangeRate.class);//步骤1
EasyMock.expect(mock.getRate("USD", "EUR")).andReturn(1.5);//步骤2
EasyMock.replay(mock);//步骤3
没错,就是这么简单,只需要3步我们就创建成功了。
1. 步骤1,使用EasyMock的静态方法createMock()创建接口的Mock对象。
2. 步骤2,使用EasyMock的静态方法expect()设置期望值。把方法作为参数传递给 EasyMock.expect() 方法。然后调用 andReturn() 指定调用这个方法应该得到什么结果。
3. 步骤3,调用 EasyMock.replay() 方法,让 mock 准备在下一次调用时重放记录的数据。
测试异常
mock 最常见的用途之一是测试异常条件。例如,无法简便地根据需要制造网络故障,但是可以创建模拟网络故障的 mock。
EasyMock.expect(mock.getRate("USD", "EUR")).andThrow(new IOException());
这里的新东西是 andThrow() 方法。顾名思义,它只是让 getRate() 方法在被调用时抛出指定的异常。
放宽测试参数
在默认情况下,EasyMock 只允许测试用例用指定的参数调用指定的方法。但是,有时候这有点儿太严格了,所以有办法放宽这一限制。例如,假设希望允许把任何字符串传递给 getRate() 方法,而不仅限于 USD 和 EUR。那么,可以指定 EasyMock.anyObject() 而不是显式的字符串,如下所示:
(String) EasyMock.anyObject(),
(String) EasyMock.anyObject())).andReturn(1.5);
类似的方法还有:
//非空参数
EasyMock.expect(mock.getRate(
(String) EasyMock.notNull(),
(String) EasyMock.notNull())).andReturn(1.5);
//正则表达式参数
EasyMock.expect(mock.getRate(
(String) EasyMock.matches("[A-Z][A-Z][A-Z]"),
(String) EasyMock.matches("[A-Z][A-Z][A-Z]"))).andReturn(1.5);
EasyMock.anyInt()
EasyMock.anyShort()
EasyMock.anyByte()
EasyMock.anyLong()
EasyMock.anyFloat()
EasyMock.anyDouble()
EasyMock.anyBoolean()
//还可以使用 EasyMock.lt(x) 接受小于 x 的任何值,或使用 EasyMock.gt(x) 接受大于 x 的任何值。
严格的mock次序检查
EasyMock 不仅能够检查是否用正确的参数调用预期的方法。它还可以检查是否以正确的次序调用这些方法,而且只调用了这些方法。在默认情况下,不执行这种检查。要想启用它,应该在测试方法末尾调用 EasyMock.verify(mock)。
检查是否只调用 getRate() 一次:
public void testToEuros() throws IOException {
Currency expected = new Currency(3.75, "EUR");
ExchangeRate mock = EasyMock.createMock(ExchangeRate.class);
EasyMock.expect(mock.getRate("USD", "EUR")).andReturn(1.5);
EasyMock.replay(mock);
Currency actual = testObject.toEuros(mock);
assertEquals(expected, actual);
EasyMock.verify(mock);
}
该功能基本上只有在大型项目中才会用到,不易理解,等需要用到时再回来查,查阅地址:https://www.ibm.com/developerworks/cn/java/j-easymock.html#artrelatedtopics