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

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

模擬界面沒有意義?

模擬界面沒有意義?

C#
寶慕林4294392 2023-04-16 10:11:37
我是單元測試的新手,感覺我在這里遺漏了一些非常重要的東西。我想在下面測試 DoSomethingWithArray 的結果:class Traffic:ITraffic{    private HugeArray _hugeArray;    public Traffic(HugeArray hugeArray)    {        _hugeArray = hugeArray;    }    public int DoSomethingWithArray()    {        var ret = 0;        //Here some code that does something with big array and stores some integer values in ret        return ret;    }}class HugeArray{    //This is my custom data structure;}interface ITraffic{    int DoSomethingWithArray();}我正在使用 Nunit,從我讀到的內容來看,模擬接口比模擬類更好。我的問題是,我想測試的是 DosomethingWithArray 在 Traffic 類中的具體功能,我很難概念化 ITraffic 接口如何適應。我在這里缺少什么?編輯這是我將如何測試我的課程[TestFixture]public class TrafficTests{    private Traffic _traffic;    private const int size = 1000000;    private const int key = 1851925790;    [OneTimeSetUp]    public void Setup()    {        var hugeArray = new HugeArray(size);        //Some Setups to create an edge case, not  relevant to my question        hugeArray.AddValue(size - 1, Int.MaxValue);        hugeArray.AddValue(size - 2, key);        //This is the object I want to test,         _traffic = new Traffic(hugeArray);    }    [Test]    public void DoSomethingWithArray_Test()    {        Assert.DoesNotThrow(() =>                            {                                var ret = _traffic.DoSomethingWithArray();                                Assert.AreEqual(ret, 233398);                            });    }} 我的問題是:這種方法看起來正確嗎?為測試創建的對象是否正常,或者我應該模擬 ITraffic 接口嗎?
查看完整描述

1 回答

?
白衣染霜花

TA貢獻1796條經驗 獲得超10個贊

在您的示例中,您正在測試Traffic. 實現無關緊要Traffic。ITraffic如果您: ITraffic從類中刪除,則它不再實現該接口,它根本不會改變您測試的方式Traffic。


你在測試Traffic。我們不會嘲笑我們正在測試的東西。我們嘲笑我們沒有測試的東西。


假設我有這個驗證地址的類:


public class AddressValidator

{

    public ValidationResult ValidateAddress(Address address)

    {

        var result = new ValidationResult();


        if(string.IsNullOrEmpty(address.Line1))

            result.AddError("Address line 1 is empty.");

        if(string.IsNullOrEmpty(address.City))

            result.AddError("The city is empty.");


        // more validations


        return result;

    }

}

這個類是否實現接口并不重要。如果我正在測試此類,則沒有什么可嘲笑的。


假設我意識到我還需要驗證郵政編碼,但為此我可能需要查詢一些外部數據以查看城市是否與郵政編碼匹配??赡懿煌膰也灰粯?。所以我寫了一個新的接口并將其注入到這個類中:


public interface IPostalCodeValidator

{

    ValidationResult ValidatePostalCode(Address address);

}


public class AddressValidator

{

    private readonly IPostalCodeValidator _postalCodeValidator;


    public AddressValidator(IPostalCodeValidator postalCodeValidator)

    {

        _postalCodeValidator = postalCodeValidator;

    }


    public ValidationResult ValidateAddress(Address address)

    {

        var result = new ValidationResult();


        if (string.IsNullOrEmpty(address.Line1))

            result.AddError("Address line 1 is empty.");

        if (string.IsNullOrEmpty(address.City))

            result.AddError("The city is empty.");


        var postalCodeValidation = _postalCodeValidator.ValidatePostalCode(address);

        if (postalCodeValidation.HasErrors)

            result.AddErrors(postalCodeValidation.Errors);


        return result;

    }

}

郵政編碼驗證非常復雜,它將在自己的類中進行自己的測試。當我們測試時,AddressValidator我們不想測試郵政編碼驗證器。我們只想隔離測試這個類,單獨測試另一個類。想要AddressValidator確保它_postalCodeValidator.ValidatePostalCode被調用,并且如果它返回錯誤,我們將它們添加到驗證結果中。


我們不在這里測試IPostalCodeValidator(或其實現),所以我們模擬它。例如,使用最小起訂量:


public void AddressValidator_adds_postal_code_errors()

{

    var postalCodeError = new ValidationResult();

    postalCodeError.AddError("Bad!");

    postalCodeError.AddError("Worse!");


    var postalCodeValidatorMock = new Mock<IPostalCodeValidator>();

    postalCodeValidatorMock.Setup(x => x.ValidatePostalCode(It.IsAny<Address>()))

        .Returns(postalCodeError);


    var subject = new AddressValidator(postalCodeValidatorMock.Object);

    var result = subject.ValidateAddress(new Address());


    Assert.IsTrue(result.Errors.Contains("Bad!"));

    Assert.IsTrue(result.Errors.Contains("Worse!"));

}

我們實際上并沒有驗證郵政編碼。我們只是說,為了測試,郵政編碼驗證器總是會返回這兩個錯誤。然后我們確保AddressValidator調用它并執行我們期望它對這些錯誤執行的操作。


這基本上就是模擬的內容。這是一個偽造的實現,它做一些簡單的事情,比如罐頭響應,這樣我們就可以確保我們按照我們期望的方式處理罐頭響應。如果AddressValidator正確處理結果,那么它就可以正常工作。完成。


為了確保真正的郵政編碼驗證器返回正確的結果,我們可以為該類編寫測試。這樣,每個班級都會做一些簡單的事情,并進行測試以確保它正確地做事。當我們將它們放在一起時,整個事情更有可能奏效。如果我們破壞的實現IPostalCodeValidator,那么該類的測試將失敗,但 的測試AddressValidator仍然會通過。這樣我們就可以快速了解哪個部分出了問題,因為它們都是單獨測試的,所以我們不必運行和調試大量代碼來試圖找出問題所在。


查看完整回答
反對 回復 2023-04-16
  • 1 回答
  • 0 關注
  • 143 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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