将Autofac和Moq与Delegate Factories一起使用

我正在尝试对使用工厂注入的类进行unit testing。 我有一个类,它实例化同一个对象的两个副本(使用不同的配置)来控制硬件。 我正在尝试在模拟硬件调用时测试类的行为。

我已经在构造函数中注入了一组工厂委托,以便类可以根据需要实例化硬件类。 但是,我无法解决如何在Autofac.Extras.Moq包中控制或创建工厂方法。 程序包似乎不支持此function。

我正在寻找一个等效的电话:

mock.Provide(//created by factory delegate) 

我想根据用于实例化HWcontroller的参数创建一个具有行为的特定模拟对象。 我甚至想做什么?

 class SystemUnderTest { SystemUnderTest(Ia a, Ib b, Ic c, /** 15 other things **/ Func<Func, HwType, IHwManager> HwManagerFactory, Func HwControllerFactory) { } } class HwManager() { public Func<HwType, Func, HwManager> Factory; public HwManager(HwType type, Func ControlFactory) { //Constructor } } 

代码我是unit testing创​​建控制器管理器。 控制器是硬件层,但我正在测试管理器内的复杂(耦合)行为。 因此,我正在尝试研究如何模拟Func ControlFactory以便它返回我的设置模拟对象,以便我可以探测管理器的行为。

我的测试系统创建了HWManager的具体实例。 我在一个完美的场景中意识到我会分别测试HwManager和SUT,但我是专门测试这两个组件的集成。

我想配置autofac来控制委托工厂。 如果这是不可能的,那么我可以手动设置SUT,但是我没有从autofac助手获得任何值。

我通常只是创建一个Func来返回我的模拟实例,例如

 var controller = mock.Provide(); var manager = new HwManager(something, (uri) => controller); 

如果工厂表示“给定一个Uri,我将提供一个控制器”,上面例子中的lamda满足该声明。

另外,您应该使用接口来表达您的工厂,而不是具体的类。 当工厂生产具体类而不是接口(总是可以模拟)时,unit testing会变得更加困难,例如

 // IHwController is the product of the factory instead of HwController public HwManager(HwType type, Func ControlFactory) 

如果有人在将来遇到困难,关键是创建一个与构造函数func匹配的函数,自定义为在每个调用上提供适当的模拟(例如通过内部计数器)。

然后,您可以使用mock.Provide()语法,提供一个与上面创建的func匹配构造函数func的函数。 然后将正确调用它,允许您适当地控制模拟。