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仍然會通過。這樣我們就可以快速了解哪個部分出了問題,因為它們都是單獨測試的,所以我們不必運行和調試大量代碼來試圖找出問題所在。
- 1 回答
- 0 關注
- 143 瀏覽
添加回答
舉報