我似乎无法弄清楚如何正确地模拟这个方法。我想模拟的方法如下:
public virtual void Publish<TEvent>(TEvent evt) where TEvent : IDomainEvent {
HandlerInvoker.Invoke(evt);
}
我想模仿的TEvent的一个例子是:
public interface IOrderPlaced : IDomainEvent {}
如果我使用的话,我可以模仿这个:
mock.Setup(h => h.Publish(It.IsAny<IOrderPlaced>));
但是,我希望模拟从IDomainEvent派生的所有接口的方法,如下所示:
mock.Setup(h => h.Publish(It.IsAny<IDomainEvent>));
但这根本不起作用。它仅在我使用特定接口设置模拟时有效。但这在我的应用程序中是完全不现实的,因为我有超过100个来自IDomainEvent的接口。更不用说如果我不得不单独模仿每一个,那将是一个野兽。有没有人看到我做错了什么?
答案 0 :(得分:1)
您遇到的问题是,您调用IDomainEvent
的{{1}}的每个不同派生都是作为具有不同签名的方法实现的。
当你使用Publish<T>()
实际上,Setup()
只会在编译器将x特别视为类型mock.Setup(h => h.Publish(It.IsAny<IDomainEvent>));
时模拟Publish<IDomainEvent>(x)
。 e.g。
IDomainEvent
不幸的是,没有办法设置模拟泛型方法的每个签名。您甚至无法在运行时使用反射遍历所有IDomainEvent派生类型 - 因为您在尝试访问通用It.IsAny()方法时遇到了完全相同的问题。
有关详细信息,请阅读this related answer以查看其他问题。
...
如果你的模拟行为是松散的,那么无论如何方法都会成功。所以我假设您要附加其他行为,例如.Returns()或.Callback()。 也许如果你详细了解预期的结果,我们可以找到另一种解决方案吗?