1 回答

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超10個(gè)贊
在您的示例中,您正在測(cè)試Traffic. 實(shí)現(xiàn)無(wú)關(guān)緊要Traffic。ITraffic如果您: ITraffic從類(lèi)中刪除,則它不再實(shí)現(xiàn)該接口,它根本不會(huì)改變您測(cè)試的方式Traffic。
你在測(cè)試Traffic。我們不會(huì)嘲笑我們正在測(cè)試的東西。我們嘲笑我們沒(méi)有測(cè)試的東西。
假設(shè)我有這個(gè)驗(yàn)證地址的類(lèi):
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;
}
}
這個(gè)類(lèi)是否實(shí)現(xiàn)接口并不重要。如果我正在測(cè)試此類(lèi),則沒(méi)有什么可嘲笑的。
假設(shè)我意識(shí)到我還需要驗(yàn)證郵政編碼,但為此我可能需要查詢(xún)一些外部數(shù)據(jù)以查看城市是否與郵政編碼匹配??赡懿煌膰?guó)家不一樣。所以我寫(xiě)了一個(gè)新的接口并將其注入到這個(gè)類(lèi)中:
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;
}
}
郵政編碼驗(yàn)證非常復(fù)雜,它將在自己的類(lèi)中進(jìn)行自己的測(cè)試。當(dāng)我們測(cè)試時(shí),AddressValidator我們不想測(cè)試郵政編碼驗(yàn)證器。我們只想隔離測(cè)試這個(gè)類(lèi),單獨(dú)測(cè)試另一個(gè)類(lèi)。想要AddressValidator確保它_postalCodeValidator.ValidatePostalCode被調(diào)用,并且如果它返回錯(cuò)誤,我們將它們添加到驗(yàn)證結(jié)果中。
我們不在這里測(cè)試IPostalCodeValidator(或其實(shí)現(xiàn)),所以我們模擬它。例如,使用最小起訂量:
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!"));
}
我們實(shí)際上并沒(méi)有驗(yàn)證郵政編碼。我們只是說(shuō),為了測(cè)試,郵政編碼驗(yàn)證器總是會(huì)返回這兩個(gè)錯(cuò)誤。然后我們確保AddressValidator調(diào)用它并執(zhí)行我們期望它對(duì)這些錯(cuò)誤執(zhí)行的操作。
這基本上就是模擬的內(nèi)容。這是一個(gè)偽造的實(shí)現(xiàn),它做一些簡(jiǎn)單的事情,比如罐頭響應(yīng),這樣我們就可以確保我們按照我們期望的方式處理罐頭響應(yīng)。如果AddressValidator正確處理結(jié)果,那么它就可以正常工作。完成。
為了確保真正的郵政編碼驗(yàn)證器返回正確的結(jié)果,我們可以為該類(lèi)編寫(xiě)測(cè)試。這樣,每個(gè)班級(jí)都會(huì)做一些簡(jiǎn)單的事情,并進(jìn)行測(cè)試以確保它正確地做事。當(dāng)我們將它們放在一起時(shí),整個(gè)事情更有可能奏效。如果我們破壞的實(shí)現(xiàn)IPostalCodeValidator,那么該類(lèi)的測(cè)試將失敗,但 的測(cè)試AddressValidator仍然會(huì)通過(guò)。這樣我們就可以快速了解哪個(gè)部分出了問(wèn)題,因?yàn)樗鼈兌际菃为?dú)測(cè)試的,所以我們不必運(yùn)行和調(diào)試大量代碼來(lái)試圖找出問(wèn)題所在。
- 1 回答
- 0 關(guān)注
- 142 瀏覽
添加回答
舉報(bào)