用JMockit寫單元測試
阿新 • • 發佈:2019-01-23
文字介紹:
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>