亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在接口默認方法中對新對象創建進行單元測試?

如何在接口默認方法中對新對象創建進行單元測試?

MYYA 2023-04-26 16:29:44
接口中有一個創建新對象并使用其功能的默認方法。所以我需要嘲笑它。但是如果不創建另一個返回新實例的默認方法,我就無法弄清楚。到目前為止,我曾經創建過處理對象創建的工廠,而不是模擬工廠方法。但不能在接口中執行此操作,因為接口不能具有在這種情況下作為工廠的實例變量。還有其他想法嗎?我想在項目中保持一致,但現在我有兩種不同的方法來避免在方法中創建對象。這是一個例子:public interface ISomeInterface{    default Integer callMe( )    {        Object someObject = new Object( ); // need to mock this        Integer result = someObject.finish();        result = result + 1;        return result;    }}當我不使用這樣的接口時,我曾經用工廠重構代碼;default Integer callMeNotInterfaceClass( ){    Object someObject = new Object( );    Integer result = instanceFactory.create().finish(); // I can mock create() method     result = result + 1;    return result;}我為包裝器方法實現的唯一解決方案:public Integer callMe( ){    Object someObject = new Object( );    Integer result = wrapperMethodCall.finish(); // only solution so far. But now I have 2 different approaches in the project to avoid object creation.    result = result + 1;    return result;}default Object wrapperMethodCall() {    return new SomeObject().someMethodsToBeMocked();}
查看完整描述

1 回答

?
守著星空守著你

TA貢獻1799條經驗 獲得超8個贊

像往常一樣,單元測試迫使您考慮類的設計。

首先,您應該注意到您有兩種主要的不同類型的對象。

有些對象是值:它們是不可變的,可以存在于多個副本中,是可比較的(并且hashCode也有一個)。這是一種易于存儲在數據庫中的對象。如果您對 Kotlin 有所了解,您就會聽說過data classes: 就是這樣。

其他一些具有實體語義的對象:它們是可變的,比較它們沒有意義,而且通常只有它們的一個副本。它們是做某事的對象。

具有實體語義的對象是您需要在單元測試中模擬的對象,而您不需要模擬值。為了傳遞模擬,這些對象必須作為構造函數的參數注入到類中。

在您的代碼片段中,您在函數中創建了一個對象,該對象似乎具有實體的語義(值什么都沒有finish),這就是您遇到問題的原因:您無法進行單元測試,因為您無法模擬該實體.

解決方案很簡單:要么在方法中注入對象:

public interface ISomeInterface

{

? ? default Integer callMe(Object someObject)

? ? {

? ? ? ? Integer result = someObject.finish();

? ? ? ? result = result + 1;


? ? ? ? return result;

? ? }


? ? ...

}

或者你在類中注入對象:


public interface ISomeInterface

{

? ? default Integer callMe()

? ? {

? ? ? ? Integer result = finishObject();

? ? ? ? result = result + 1;


? ? ? ? return result;

? ? }


? ? // classes will need an instance of the object to implement this

? ? Integer finishObject();?


? ? ...

}

在這兩種情況下,實現您的接口的類要么負責在調用方法時提供對象本身,要么負責返回方法的值finish。


但請記住:如果您在這些類的方法中創建對象,對它們進行單元測試也會變得困難。使用工廠模式在靜態方法中創建實體對象并將這些對象傳遞給構造函數。


如果遵循這條經驗法則,類和方法的單元測試將變得更容易:當對象具有語義值時,在更高級別創建它(如果可能)并將其作為構造函數或方法的參數main傳遞。


查看完整回答
反對 回復 2023-04-26
  • 1 回答
  • 0 關注
  • 156 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號