将Autofac和Moq与Delegate Factories一起使用

时间:2015-04-14 23:56:00

标签: c# moq autofac

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

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

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

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

我想根据用于实例化HWcontroller的参数创建一个具有行为的特定模拟对象。我正在努力做甚么可能吗?

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帮助器中获得任何值。

2 个答案:

答案 0 :(得分:2)

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

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

如果工厂正在表达&#34;给定一个Uri,我将提供一个控制器&#34;,上面例子中的lamda满足该声明。

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

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

答案 1 :(得分:0)

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

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