将Autofac和Moqs与代理工厂一起使用



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

我在构造函数中注入了一组工厂委托,这样类就可以根据需要实例化硬件类。然而,我就是不知道如何在Autofac中控制或创建工厂方法。额外费用。Moq包。软件包中似乎不支持此功能。

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

mock.Provide<IHWController>(//created by factory delegate)

我想根据用于实例化HWcontroller的参数,创建一个具有行为的特定mock对象。我想做的事情有可能吗?

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

我正在进行单元测试的代码创建控制器的管理器。控制器是硬件层,但我正在测试管理器内部的复杂(耦合)行为。因此,我正试图找出如何模拟Func<Uri, HwController> ControlFactory,以便它返回我的设置模拟对象,以便我可以探测管理器的行为。

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

我想配置autofac来控制代理工厂。如果这不可能,那么我可以手动设置SUT,但我不会从autofac助手中获得任何值。

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

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

如果工厂表示"给定一个Uri,我将提供一个控制器",那么我上面的例子中的lamda满足该语句。

顺便说一句,您应该使用接口而不是具体的类来表达您的工厂。当工厂生产具体的类而不是接口(这总是可以模拟的)时,这使得单元测试变得更加困难,例如

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

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

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

最新更新