简体   繁体   中英

Using AutoFac Property Injection with Moq

Consider the following class:

public class ViewModelBase
{
    public IService Service { get; protected set; }
}

and this test for the class:

using var mock = AutoMock.GetLoose();
var viewModelBase = mock.Create<ViewModelBase>();
Assert.NotNull(viewModelBase.Service);

In my normal application, I'm using the property injection functionality of Autofac.Core.NonPublicProperty to autowire the IService dependency into the ViewModelBase :

containerBuilder.RegisterType(typeof(ViewModelBase)).AutoWireNonPublicProperties();

In the test, I'm using the Autofac.Extras.Moq integration package to automatically mock dependencies for ViewModelBase . However, as far as I can tell, only constructor injection is supported by Autofac.Extras.Moq . This causes the test to fail because the Service property is not autowired by Moq.

Is there any elegant way of utilizing the property injection function of AutoFac with Moq?

only constructor injection is supported by Autofac.Extras.Moq

Actually you are right, but the AutoMock.GetLoose has an overload in which you can inject to the mock a fully functioned IContainer by passing a delegate of ContainerBuilder with all the regular autofac features:

public class AutoMock : IDisposable
{
    //...  
    public IContainer Container { get; }
    public static AutoMock GetLoose(Action<ContainerBuilder> beforeBuild);
    //...
}

In your case the extension Autofac.Extras.Moq is not supporting the PropertiesAutowired() method so we can build a ContainerBuilder and pass it with a delegate:

Action<ContainerBuilder> containerBuilderAction = delegate(ContainerBuilder cb)
{
    cb.RegisterType<ServiceFoo>().As<IService>();
    cb.RegisterType<ViewModelBase>().PropertiesAutowired(); //The autofac will go to every single property and try to resolve it.
};

var mock = AutoMock.GetLoose(containerBuilderAction);
        
var viewModelBase = mock.Create<ViewModelBase>();            
Assert.IsNotNull(viewModelBase.Service);

With IService implementation class of ServiceFoo :

public class ServiceFoo : IService` { }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM