Using Autofac and Moqs with Delegate Factories

一笑奈何 提交于 2019-12-12 12:28:38

问题


I am trying to unit test a class that uses factory injection. I have a class that instantiates two copies of the same object (with different config) to control hardware. I'm trying to test the behaviour of the classes while simulating the hardware calls.

I've injected a set of factory delegates into the constructors so that the class can instantiate the hardware classes as required. However I just can't work out how to control or create factory methods within the Autofac.Extras.Moq package. It seems that this functionality isn't supported in the package.

I'm looking for an equivalent call to :

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

I want to create a specific mock object with behaviour, based on the parameters used to instantiate the HWcontroller. Is what I'm trying to do even possible?

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
    }
}

The code I'm unit testing creates Managers of controllers. The controller is the hardware layer, but I'm testing complex (coupled) behaviour inside the manager. Therefore, I'm trying to work out how to mock the Func<Uri, HwController> ControlFactory so that it returns my setup mock objects so that I can probe the behaviour of the manager.

My system under test creates a concrete instantiation of the HWManager. I realise in a perfect scenario I would test the HwManager and SUT separately, but I'm specifically testing the integration of the two components.

I'd like to configure the autofac to control the delegate factory. If this isn't possible, then I can manually setup the SUT, but then I don't get any value from the autofac helper.


回答1:


I usually just create a Func that returns my mocked instance e.g.

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

If the factory is expressing "given a Uri I will provide a controller", the lamda in my example above satisfies that statement.

As an aside, you should express your factories using interfaces, not concrete classes. It makes it a lot harder to unit test when the factories are producing concrete classes instead of interfaces (which can always be mocked) e.g.

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



回答2:


If anyone gets stuck on this in the future, the key is to create a func that matches the constructor func, customised to provide the appropriate mocks on each invokation (e.g. via an internal counter).

You can then use the mock.Provide() syntax, providing a func that matches the constructor func with your created func above. This will then be invoked correctly allowing you to control the mocks appropriately.



来源:https://stackoverflow.com/questions/29639360/using-autofac-and-moqs-with-delegate-factories

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!