文字介绍:
Mock 测试是一种常见的测试方法。通常在执行测试的时候,测试代码往往需要与一些真实对象进行交互,又或者被测代码的执行需要依赖真实对象的功能。此时,我们可以使用一个轻量级的、可控制的 Mock 对象来取代真实对象,模拟真实对象的行为和功能,从而方便我们测试。 jMock 便是这种方法的一种实现。
JMock 是一个利用Mock对象来测试Java代码的轻量级测试工具。毫不例外,它也是xUnit家族的一员,因为它从JUnit发展而来,是JUnit的一个增强库。jMock用法简单,易于掌握。利用它,我们可以很容易地快速构造出所需的Mock对象,从而得以方便快捷地编写单元测试代码,很适合测试驱动开发的流畅进行。
我遇到的例子,上代码:
public class InnerCustomerInfoServiceTest extends BaseServiceTest { @SpringBeanByType InnerCustomerInfoService innerCustomerInfoService;//由spring bean注入接口的实现类 //... /** * 参数对应返回为NULL的逻辑判断 */ @Test public void test1_FindCustomerInfo() { new MockUp<IbatisCustomerInfoDAO>() {//说明1 @Mock CustomerInfoDO findCustomerInfo(long customerId) { want.number(customerId).isEqualTo(2); return null; } }; CustomerInfoDO entity = innerCustomerInfoService.findCustomerInfo(2);//此处的方法调用代码,见说明1 Assert.assertTrue(entity == null); } /** * 第一次就正确找到参数对应的值的逻辑测试 */ @Test public void test2_findCustomerInfoByKpId() { new MockUp<IbatisCustomerInfoDAO>() { @Mock CustomerInfoDO findCustomerInfoByKpId(long kpId) { want.number(kpId).isEqualTo(1); CustomerInfoDO tmpDO = new CustomerInfoDO(); tmpDO.setCustomerRank(2); return tmpDO; } }; CustomerInfoDO entity = innerCustomerInfoService.findCustomerInfoByKpId(1); want.number(entity.getCustomerRank()).isEqualTo(2);//说明2 } /** * 第一次没找到对应值 补全后正确找到参数对应的值的逻辑测试 */ @Test public void test3_findCustomerInfoByKpId() { new MockUp<IbatisCustomerInfoDAO>() { @Mock CustomerInfoDO findCustomerInfoByKpId(long kpId) { want.number(kpId).isEqualTo(1); return null; } }; new MockUp<InnerCustomerInfoServiceImpl>() {//说明3 @Mock CustomerInfoDO createNewCustomerInfoByKpId(long kpId) { want.number(kpId).isEqualTo(1); CustomerInfoDO tmpDO = new CustomerInfoDO(); tmpDO.setCustomerRank(2); return tmpDO; } }; CustomerInfoDO entity = innerCustomerInfoService.findCustomerInfoByKpId(1); want.number(entity.getCustomerRank()).isEqualTo(2); } //... }
说明:
1. new MockUp<IbatisCustomerInfoDAO>,为什么是IbatisCustomerInfoDAO?说明需要模拟IbatisCustomerInfoDAO这个对象。方法调用的代码实现:
public class InnerCustomerInfoServiceImpl implements InnerCustomerInfoService { private static final Log log = LogFactory.getLog(InnerCustomerInfoServiceImpl.class); @Autowired private CustomerInfoDAO customerInfoDAO; @Override public CustomerInfoDO findCustomerInfo(long customerId) { if (customerId <= 0) { log.error("param error,customerId is: " + customerId); return null; } return customerInfoDAO.findCustomerInfo(customerId);//此处用到了CustomerInfoDAO接口对象,故需要进行模拟, //说明1模拟了其实现类IbatisCustomerInfoDAO的对象 } //... }
2. want的意思?想想上面的Assert.assertTrue..
3. 两个mock?说明用到了两个对象,需要模拟两个对象。具体代码和说明1雷同。其实很简单,照葫芦画瓢即可!
4.关于使用JMock需要导入的Jar包?本例中已经由Maven同一配置管理了,在jtester里,pom.xm相关部分如下图:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <dependency> <groupId>com.NB.jtester</groupId> <artifactId>jtester.junit</artifactId> <version>${jtester_version}</version> </dependency> <dependency> <groupId>com.NB.jtester</groupId> <artifactId>jtester.integrated</artifactId> <version>${jtester_version}</version> </dependency> <dependency> <groupId>com.NB.jtester</groupId> <artifactId>jtester.spec</artifactId> <version>${jtester_version}</version> </dependency>
官方地址: