簡體   English   中英

應該在單元測試中模擬簡單的類還是應該直接使用/測試它們?

[英]Should simple classes be mocked in unit-tests or should they be used/tested directly?

我不確定我的方法TranslateResponse()還可以測試什么。

它基本上檢查翻譯器的類型並調用翻譯器相關的set()方法。

public async Task TranslateResponse(Policy response)
{
    foreach (var t in await _translatorFactory.BuildTranslators())
    {
        var policyTranslator = t as IPolicyAwareTranslator;
        policyTranslator?.SetPolicy(response);
        var additionalInterestTranslator = t as IAdditionalInterestAwareTranslator;    
        additionalInterestTranslator?.SetAdditionalInterests(response.AdditionalInterests);
        var locationsTranslator = t as ILocationsAwareTranslator;
        locationsTranslator?.SetLocations(response.Locations);
    }
}

我正在為TranslateResponse()方法編寫測試用例。 據我所知,我正在驗證對相應方法的調用是否基於提供的翻譯器類型發生。 測試用例行

Mock<ITranslator> mockedTranslator = new Mock<ITranslator>(); 
mockedTranslator.Setup(t => t.Translate(_translatorDataAccessor.Object));

var mockedPolicyTranslator = mockedTranslator.As<IPolicyAwareTranslator>();
mockedPolicyTranslator.Setup(t => t.SetPolicy(It.IsAny<Policy>()));

mockedPolicyTranslator.Verify(t => t.SetPolicy(It.IsAny<Policy>()), Times.AtLeastOnce);

我的擔憂是

  1. 我很想知道我是否可以測試比驗證呼叫更多的東西?

  2. 我應該在這里還是在它自己的類中測試 set() 方法的邏輯? 即使這樣,我也無法弄清楚在Set()的測試用例中要斷言什么,這將使用傳入的參數設置私有字段。

public class PolicyTranslator : ITranslator, IPolicyAwareTranslator
{      
    private Policy _policy;        
    public void SetPolicy(Policy policy)
    {
        _policy = policy;
    }  
    //translate()
}      

我是否可以測試比驗證呼叫更多的東西?

基本上沒有更多可以測試的,只是

  1. 為每個使用的接口添加相同的測試

此外,您可能想要

  1. 測試實現所有接口的東西實際上是作為每個接口處理的
  2. 也許還有一個測試可以驗證是否存在 foreach 循環(多個翻譯器)而不僅僅是.FirstOrDefault()
  3. 此外,沒有返回BuildTranslators元素的BuildTranslators也是有效的。

我應該在這里還是在它自己的類中測試 set() 方法的邏輯?

在大多數情況下,不應在單元測試中測試SUT依賴項,因為

  1. 它可能不再是單元測試(如果依賴關系足夠復雜)——並不是那么重要(除非你對單元測試有一個非常嚴格的定義),但正如我們在下面看到的。
  2. 通過消費者測試依賴項通常會不必要地使測試復雜化
    • 您必須設置(通常是重要的)依賴項本身。
    • 您必須自行設置其使用者/用戶/SUT。
    • 然后,您必須以實際調用該依賴項的方式構建測試。
    • 然后驗證依賴項及其使用者是否按預期工作。
    • 並且測試的復雜性/數量不會線性增長 - 如果您可以通過 4 個 SUT 測試和 4 個其依賴項獲得 100%/合理的覆蓋率,而通過集成級別測試實現相同程度的覆蓋率可能需要 4 到 4 個*4個甚至更多的測試。

對於簡單的情況,例如,有問題的代碼實際上會簡化事情,因為您不再需要模擬IPolicyAwareTranslator並且可以簡單地測試按預期設置的值,但即使在這種情況下也有一個小陷阱:

  1. 我們不能再確定該方法處理IPolicyAwareTranslator - 有人可以將var policyTranslator = t as IPolicyAwareTranslator;替換var policyTranslator = t as IPolicyAwareTranslator; 使用var policyTranslator = t as PolicyTranslator; 並且測試仍然會通過,盡管它不能再處理我們的關鍵業務AwesomePolicyAwareTranslator

您可能會說它基本上是 電影情節威脅,如果您知道自己在做什么並且不太費力,則只需將多個類作為一個子系統進行測試。

盡管在大多數情況下,我會反對這種“低級集成測試”,當您可以進行適當的隔離時,更簡單! 單元測試

低級集成測試 - 這基本上是一個虛構的術語,但我會說它非常適合此類測試。


盡管如此,在某些情況下,粗粒度的“低級集成測試”可能比包含相同代碼的單元測試略好:

  1. 通常,當單個組件最終變得如此之小,以至於對它們進行單元測試不允許您表達領域概念/在眾多真實場景​​中具有任何真正程度的信任時,就會發生這種情況,而測試 金字塔更高的 測試太少了/難以運行/維護。

在這種情況下,“低級集成測試”以合理的價格為您提供了很多(我們不應該忘記 100% 的覆蓋率是無法獲得的,不能以低廉的價格構建適當的測試金字塔,因此具有成本效益的測試方法是必需品)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM