gpt4 book ai didi

c# - 当代码验证它接收到的类型时如何使用模拟

转载 作者:行者123 更新时间:2023-11-30 22:35:03 25 4
gpt4 key购买 nike

我想测试下面的代码:

public IEnumerable<KeyValuePair<Fact, Exception>> ValidateAll()
{
//...do something
var invalidFacts = GetInvalidFacts();
//...do something

return duplicateFacts.Concat(invalidFacts);
}

private IEnumerable<KeyValuePair<Fact, Exception>> GetInvalidFacts()
{
var invalidFacts = Facts.Select(fact =>
{
try
{
fact.Validate();
return new KeyValuePair<Fact, Exception>(fact, null);
}
catch (FormatException e)
{
return new KeyValuePair<Fact, Exception>(fact, e);
}
catch (Exception e)
{
return new KeyValuePair<Fact, Exception>(fact, e);
}
}).Where(kv => kv.Value != null).ToList();

return invalidFacts;
}

基本上,测试的目标是验证“Facts”IEnumerable 中存在的所有对象是否会调用它们的 Validate 方法。因为我对测试这些对象中的代码不感兴趣,所以已经有很多测试可以做到这一点,我想注入(inject)一个虚假事实列表。我正在使用最小起订量来制造假货。

所以我的单元测试看起来像这样:

[TestMethod]
public void ValidateAll_ValidateMethodIsInvokedOnAllFacts_WhenCalled()
{
var anyFactOne = new Mock<Fact>(); //Fact is an abstract class.

anyFactOne.Setup(f => f.Validate());

var dataWarehouseFacts = new DataWarehouseFacts { Facts = new Fact[] { anyFactOne.Object, FactGenerationHelper.GenerateRandomFact<SourceDetails>() } };

dataWarehouseFacts.ValidateAll();
}

现在我得到一个异常,因为代码实际上正在验证可以注入(inject)到 DataWarehouseFacts 类的事实类型,如下所示:

public IEnumerable<Fact> Facts
{
get
{
.....
}
set
{
var allowedTypes = new []
{
typeof(ProductUnitFact),
typeof(FailureFact),
typeof(DefectFact),
typeof(ProcessRunFact),
typeof(CustomerFact),
typeof(ProductUnitReturnFact),
typeof(ShipmentFact),
typeof(EventFact),
typeof(ComponentUnitFact),
typeof(SourceDetails)
};

if(!value.All(rootFact => allowedTypes.Contains(rootFact.GetType())))
throw new Exception ("DataWarehouseFacts can only be set with root facts");

ProductUnitFacts = value.OfType<ProductUnitFact>().ToList();
FailureFacts = value.OfType<FailureFact>().ToList();
DefectFacts = value.OfType<DefectFact>().ToList();
ProcessRunFacts = value.OfType<ProcessRunFact>().ToList();
CustomerFacts = value.OfType<CustomerFact>().ToList();
ProductUnitReturnFacts = value.OfType<ProductUnitReturnFact>().ToList();
ShipmentFacts = value.OfType<ShipmentFact>().ToList();
EventFacts = value.OfType<EventFact>().ToList();
ComponentUnitFacts = value.OfType<ComponentUnitFact>().ToList();
SourceDetails = value.OfType<SourceDetails>().Single();
}
}

绕过此验证的最佳方法是什么?

谢谢。

最佳答案

两个显而易见的方法是:

  1. Fact 添加到您的允许类型列表中。
  2. Moq 您允许的事实类型之一,而不是基础 Fact 类本身。 (我假设您的 Validate() 方法是可覆盖的。)

另一个稍微复杂的选项是在测试时注入(inject)允许类型列表,假设您可以控制 DataWarehouseFacts 类。这可能看起来像这样:

class DWF
{
static IEnumerable<Fact> defaultAllowedFacts = new Fact[] { ... }
IEnumerable<Fact> allowedFacts;

public DWF() : this(defaultAllowedFacts) { ... }
internal DWF(IEnumerable<Fact> allowed)
{
// for testing only, perhaps
this.allowedFacts = allowed;
}
...
}

然后只需删除 var allowedTypes = new [] 位并改用 this.allowedFacts

关于c# - 当代码验证它接收到的类型时如何使用模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7575782/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com