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

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

在單元測試中避免外部輸入

在單元測試中避免外部輸入

慕無忌1623718 2023-02-23 18:09:38
我想對 a 進行單元測試class A。這個類與其他類級聯,所以class A創建了一個實例class B和class B的class C。像那樣:public class A {    public B b;    public A() {        this.b = new B();    }} public class B {    public C c;    public B() {        this.c = new C();    }} 如果現在類 C 在其構造函數中讀取任何外部輸入,如文件或屬性,我如何避免這種情況?我看不出你會如何模擬它,但是在測試時是否也有可能將外部因素排除在其他類之外?
查看完整描述

4 回答

?
心有法竹

TA貢獻1866條經驗 獲得超5個贊

您在這里遇到的問題是您的類與其他類的特定實現緊密耦合,因此您的“單元”被迫一起測試所有這些類的行為。


避免這種情況的典型方法是使用依賴注入,使您的類與接口而不是特定類耦合。然后您可以模擬注入的接口以對單個類的行為進行單元測試。


public class AImpl {

    public B b;

    public AImpl(B b) {

        this.b = b;

    }

}


public interface B {

    // methods

}


public class BImpl implements B {

    public C c;

    public BImpl (C c) {

        this.c = c;

    }

}

當您創建AImpl生產代碼時,您現在必須為其提供特定的C實現。您可以這樣做new AImpl(new BImpl(new CImpl)),也可以使用像 Spring 這樣的依賴注入框架來為您計算出所有這些細節。


B當您進行單元測試時,您可以創建一個模擬或存根以具有您希望為該特定測試展示的行為,并將該存根傳遞給構造函數: new AImpl(myMockedB)。


查看完整回答
反對 回復 2023-02-23
?
慕絲7291255

TA貢獻1859條經驗 獲得超6個贊

B您不應該在類中創建實例A- 相反,您應該B在創建時提供實例A- 它稱為Inversion of Control。流行的方法是使用依賴注入,例如使用 Spring 框架。

然后一切都變得簡單 - 當您的類需要讀取帶有類的文件時FileReader,為了測試您可以創建一個“假”實現,例如當您調用時FileReader.readFile(),您的假實現將簡單地返回硬編碼字符串或流,具體取決于您想要什么。

這個概念真的很大,想象一下當你FileReader實際上是一個DatabaseReaderor ExternalServiceCaller。不是在單元測試中測試真實的數據庫(祝你好運),而是創建一個FakeDatabaseReader在常規 Java 上運行的數據庫HashMap,一切都很容易測試。

或者當您的代碼處理時間/日期時,想象一個功能只在29th February- 您可以等待 4 年來測試它,或者為Clock您的測試提供一個設置為特定日期的對象。該類Clock具有提供各種替代時鐘的靜態方法,以提供固定時刻、調整到未來或過去的時刻,或具有改變節奏的時鐘


查看完整回答
反對 回復 2023-02-23
?
瀟湘沐

TA貢獻1816條經驗 獲得超6個贊

首先,由于您不能注入 B 類,因此所有此類都不是為了進行溫和測試而設計的,請注意,由于您將任何新內容添加到類中,這與對實例進行硬編碼非常相似。


適當的方式應該是


  public class A {

    public B b;

    public A(B b) {

        this.b = b;

    }

}

請注意,您可以通過這種方式實例化類


A a = new A(b); 

這樣,b 可以是模擬或虛擬或存根或任何用于測試目的的對象。如果您面臨遺留代碼,您應該重構它以使其能夠被測試。如果這是您的設計,您應該盡快重構以使其可測試。


控制反轉和依賴注入應該有助于歸檔你想做的事情。


查看完整回答
反對 回復 2023-02-23
?
慕尼黑5688855

TA貢獻1848條經驗 獲得超2個贊

不是我知道的,你會處理這些外部因素,或者在 A、B 或 C 類本身的開發過程中確保在測試過程中不會出現此類問題。

但是,如果您無法控制 A、B 或 C 類源,那么我認為您被卡住了!


查看完整回答
反對 回復 2023-02-23
  • 4 回答
  • 0 關注
  • 126 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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