【发布时间】:2017-04-12 03:56:21
【问题描述】:
我有一个实体和一个验证器:
public class Customer : IEntity { /* ... */ }
public class CustomerValidator : IValidator<Customer> { /* ... */ }
我想模拟验证器工厂:
public interface IValidatorFactory
{
IValidator<TEntity> create<TEntity>(TEntity entity) where TEntity : class, IEntity;
}
我的模拟:
var mockFactory = Substitute.For<IValidatorFactory>();
mockFactory.create(Arg.Any<Customer>()).Returns(m => new CustomerValidator());
当参数是 Customer 时,此方法有效。
但我正在测试的代码通过了IEntity,所以模拟不起作用。
我可以重写模拟来处理输入到接口而不是具体类的参数吗?
【问题讨论】:
-
我尝试了以下变体,但无法编译
mock.create(Arg.Is<IEntity>(a => a is Customer)).Returns(m => new CustomerValidator());错误为Cannot convert lambda expression to type 'IValidator<IEntity>' because it is not a delegate type -
不可能同时拥有协变和逆变。我相信测试不应该强加架构决策。仍然可以编写可测试的代码,而无需为测试调整代码。
-
@grokky - 你能分享正在测试的代码/方法吗?我认为如果我们有更多的背景信息会有所帮助。
-
@grokky 我正在尝试弄清楚您的真实代码如何使用
CustomerValidator作为IValidator<IEntity>?无论您的真实代码在做什么,您都需要在测试中采用类似的方法。就问题的 NSub 部分而言,我认为重点是确保正确的通用实例被存根,create<IEntity>()而不是create<Customer>(如亚历山大的回答所示)。剩下的就是弄清楚你希望这些类型如何组合在一起。 :) -
@DavidTchepak 谢谢你,我已经用你和亚历山大的建议解决了这个问题。问题不是 NSubstitute,而是 SUT 的通用设计。类型如何“挂在一起”是真正的问题! :)
标签: .net unit-testing mocking nsubstitute