Im writing a test for an automapper map. One of the destination members in the map requires a value resolver, and that value resolver has service dependencies which are injected. I want to use the real implementation for the resolver (since thats part of the map im testing) but Id like to use mocks for the dependencies the resolver has.
Ofcourse I want to try to avoid using an ioc container for in my tests, but how do I easily resolve my value resolver's dependencies without one?
This is my rather simplified example, in the real case there are several resolvers with sometimes many dependencies, and I really dont like to basically implement my own dependency resolver in my tests. Should I use a lightweight ioc container?
[TestFixture]
public class MapperTest
{
private IMyService myService;
[SetUp]
public void Setup()
{
Mapper.Initialize(config =>
{
config.ConstructServicesUsing(Resolve);
config.AddProfile<MyProfile>();
});
}
public T Resolve<T>()
{
return (T) Resolve(typeof (T));
}
public object Resolve(Type type)
{
if (type == typeof(MyValueResolver))
return new MyValueResolver(Resolve<IMyService>());
if (type == typeof(IMyService))
return myService;
Assert.Fail("Can not resolve type " + type.AssemblyQualifiedName);
return null;
}
[Test]
public void ShouldConfigureCorrectly()
{
Mapper.AssertConfigurationIsValid();
}
[Test]
public void ShouldMapStuff()
{
var source = new Source() {...};
var child = new Child();
myService = MockRepository.GenerateMock<IMyService>();
myService .Stub(x => x.DoServiceStuff(source)).Return(child);
var result = Mapper.Map<ISource, Destination>(source);
result.Should().Not.Be.Null();
result.Child.Should().Be.SameInstanceAs(child);
}
}
public class MyProfile : Profile
{
protected override void Configure()
{
base.Configure();
CreateMap<ISource, Destination>()
.ForMember(m => m.Child, c => c.ResolveUsing<MyResolver>());
}
}
public class MyResolver: ValueResolver<ISource, Destination>
{
private readonly IMyService _myService;
public MyResolver(IMyService myService)
{
_myService = myService;
}
protected override Child ResolveCore(ISource source)
{
return _myService.DoServiceStuff(source);
}
}
}
To test our configuration, we simply create a unit test that sets up the configuration and executes the AssertConfigurationIsValid method: var configuration = new MapperConfiguration(cfg => cfg. CreateMap<Source, Destination>()); configuration. AssertConfigurationIsValid();
CreateMap<EFAddress, Address>() . ForMember(dest => dest. Code, opt => opt. MapFrom(src => src.Name));
Your configuration (e.g. Automapper Profiles) are singletons. That is, they are only ever loaded once when your project runs. This makes sense since your configurations will not change while the application is running. The IMapper interface itself is “scoped”.
Here's one solution, but basically its what iv done already:
http://groups.google.com/group/automapper-users/browse_thread/thread/aea8bbe32b1f590a/f3185d30322d8109
The suggestion is to use a service locator which are set up differently depending on test or real implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With