生活随笔
收集整理的這篇文章主要介紹了
(四)JMockit 的API:@Injectable 与 @Mocked的不同--基础篇
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
@Injectable 與 @Mocked的不同
import mockit.Injectable;
import mockit.Mocked;
import org.junit.Assert;
import org.junit.Test;import java.util.Locale;//@Mocked 與@Injectable的不同
public class MockedAndInjectable {@Testpublic void testMocked(@Mocked Locale locale){//靜態(tài)方法不起作用了,返回了nullAssert.assertTrue(Locale.getDefault() == null);//非靜態(tài)方法(返回類型為string)也不起作用,返回了nullAssert.assertTrue(locale.getCountry() == null);//自己new一個(gè),也同樣如此,方法都被mock了Locale chinaLocale = new Locale("zh","CN");Assert.assertTrue(chinaLocale.getCountry() == null);}@Testpublic void testInjectable(@Injectable Locale locale){//靜態(tài)方法不mockAssert.assertTrue(Locale.getDefault() != null);//非靜態(tài)方法(返回類型為string)也不起作用了,返回null,但僅僅限于locale這個(gè)對(duì)象Assert.assertTrue(locale.getCountry() == null);//自己new一個(gè),并不受影響Locale chinaLocale = new Locale("zh","CN");Assert.assertTrue(chinaLocale.getCountry().equals("CN"));}
}
- @Injectable 也是告訴 JMockit生成一個(gè)Mocked對(duì)象,但@Injectable只是針對(duì)其修飾的實(shí)例,而@Mocked是針對(duì)其修飾類的所有實(shí)例。
- 此外,@Injectable對(duì)類的靜態(tài)方法,構(gòu)造函數(shù)沒有影響。因?yàn)樗挥绊懩骋粋€(gè)實(shí)例嘛!
@Tested & @Injectable 兩個(gè)好基友,通常搭配使用
為便于演示,我們以電商網(wǎng)站下訂單的場景為例:在買家下訂單時(shí),電商網(wǎng)站后臺(tái)程序需要校驗(yàn)買家的身份(是否合法,例如是否在黑名單中),若下訂單沒有問題還要發(fā)郵件給買家。 相信下面的代碼,你一定能看明白 。
// 郵件服務(wù)類,用于發(fā)郵件
public interface MailService {/*** 發(fā)送郵件* @param userId 郵件接受人id* @param content 郵件內(nèi)容* @return 發(fā)送成功了,就返回true,否則返回false*/public boolean sendMail(long userId, String content);
}
// 用戶身份校驗(yàn)
public interface UserCheckService {/*** 校驗(yàn)?zāi)硞€(gè)用戶是否是合法用戶* * @param userId 用戶ID* @return 合法的就返回true,否則返回false */public boolean check(long userId);
}//訂單服務(wù)類 ,用于下訂單
import javax.annotation.Resource;public class OrderService {//郵件服務(wù)類,用于向某用戶發(fā)郵件MailService mailService;@ResourceUserCheckService userCheckService;//構(gòu)造函數(shù)public OrderService(MailService mailService){this.mailService = mailService;}/** 下訂單* @param buyerId 買家ID* @param itemId 商品ID* @return 返回下訂單是否成功* */public boolean submitOrder(long buyerId, long itemid){//先校驗(yàn)用戶身份if(!userCheckService.check(buyerId)){//用戶身份不合法return false;}/*下單邏輯代碼省略。。。。下單完成后,給買家發(fā)郵件* */if (!this.mailService.sendMail(buyerId, "下單成功")){//郵件發(fā)送失敗return false;}return true;}
}
假設(shè)現(xiàn)在我們需要測試OrderService類的submitOrder方法,可是OrderService依賴MailService,UserCheckService類,在測試過程中,我們并不想真正連結(jié)郵件服務(wù)器,也不想連結(jié)校驗(yàn)用戶身份的服務(wù)器校驗(yàn)用戶身份,怎么辦呢?
此時(shí)@Tested與@Injectable就排上用場了!請(qǐng)看下面的測試程序:
import mockit.Expectations;
import mockit.Injectable;
import mockit.Tested;
import org.junit.Test;//@Tested 與@injectable搭配使用
public class TestedAndInjectable {//@Tested 修飾的類,表示是我們要測試對(duì)象,在這里表示,我想測試訂單服務(wù)類。JMockit也會(huì)幫我們實(shí)例化這個(gè)測試對(duì)象@TestedOrderService orderService;long testUserId = 1234561; //測試用戶idlong testItemId = 4567891; //測試商品id//測試注入方式@Testpublic void testSubmitOrder(@Injectable MailService mailService,@Injectable UserCheckService userCheckService){new Expectations(){{//當(dāng)向testUserId發(fā)郵件時(shí),假設(shè)都發(fā)成功了mailService.sendMail(testUserId,anyString);result = true;//當(dāng)檢驗(yàn)testUserId的身份時(shí),假設(shè)該用戶都是合法的userCheckService.check(testUserId);result = true;}};//JMockit 幫我們實(shí)例化了mailService了,并通過OrderService的構(gòu)造函數(shù),注入到OrderService對(duì)象中//JMockit 幫我們實(shí)例化了userCheckService了,并通過OrderService的屬性,注入到OrderService對(duì)象中Assert.assertTrue(orderService.submitOrder(testUserId, testItemId));}
}
@Tested & @Injectable功能總結(jié)
@Injectable 也表示一個(gè)Mocked對(duì)象,相比@Mocked,只不過只影響類的一個(gè)實(shí)例。而@Mocked默認(rèn)是影響類的所有實(shí)例。@Tested表示被測試對(duì)象。如果該對(duì)象沒有賦值,JMockit會(huì)去實(shí)例化它。
@Tested的構(gòu)造函數(shù)有參數(shù),則JMockit通過在測試屬性&測試參數(shù)中查找@Injectable修飾的Mocked對(duì)象注入@Tested對(duì)象的構(gòu)造函數(shù)來實(shí)例化,不然,則用無參構(gòu)造函數(shù)來實(shí)例化。除了構(gòu)造函數(shù)的注入,JMockit還會(huì)通過屬性查找的方式,把@Injectable對(duì)象注入到@Tested對(duì)象中。
注入的匹配規(guī)則:先類型,再名稱(構(gòu)造函數(shù)參數(shù)名,類的屬性名)。若找到多個(gè)可以注入的@Injectable,則選擇最優(yōu)先定義的@Injectable對(duì)象。當(dāng)然,我們的測試程序要盡量避免這種情況出現(xiàn)。因?yàn)榻o哪個(gè)測試屬性/測試參數(shù)加@Injectable,是人為控制的。
什么測試場景,我們要使用@Tested & @Injectable
顯然,當(dāng)我們需要手工管理被測試類的依賴時(shí),就需要用到@Tested & @Injectable。
兩者搭配起來用,JMockit就能幫我們輕松搞定被測試類及其依賴注入細(xì)節(jié)。
總結(jié)
以上是生活随笔為你收集整理的(四)JMockit 的API:@Injectable 与 @Mocked的不同--基础篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。