Java开发测试工具用法简略记录——Junit4 And EasyMock

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值