问题
I'm having trouble writing tests around a factory that uses Autofac keyed registrations.
In an Autofac module, I register things like this:
builder.RegisterType<TypeAMessageHandler>().As<IMessageHandler>()
.Keyed<IMessageHandler>(MessageTypeEnum.A);
builder.RegisterType<TypeBMessageHandler>().As<IMessageHandler>()
.Keyed<IMessageHandler>(MessageTypeEnum.B);
builder.RegisterType<MessageHandlerFactory().As<IMessageHandlerFactory>();
Then the constructor for the factory gets a nice Index injected into its constructor by Autofac:
public MessageHandlerFactory(
IIndex<MessageTypeEnum, IMessageHandler> messageTypeToHandlerMap)
However, I can't figure out how to inject an IIndex<,>
for unit testing with Automock, when I use automock.Create<MessageHandlerFactory>()
. Telling the AutoMock to Provide message handler implementations doesn't get them into the keyed index. Creating an explicit implementation of IIndex and asking Automock to Provide that also doesn't work - in both cases, my factory gets an empty IIndex<,>
injected.
What is the right way to test keyed registrations?
回答1:
I found the AutoMock doesn't really have built in support for keyed components, but does has overloads of the factory methods that let you configure the container.
So this works:
var messageAMock = new Mock<IMessageHandler>();
var autoMock = AutoMock.GetStrict(builder => builder.RegisterInstance(messageAMock.Object).Keyed<IMessageHandler>(MessageTypeEnum.A));
回答2:
Well, I've managed to work around the issue by explicitly building the SUT:
internal class MockIndex<T, T1> : Dictionary<T, T1>, IIndex<T, T1>
{
}
IIndex<FileTransportTypeEnum, IMessageHandler> index = new MockIndex<MessageTypeEnum, IMessageHandler>
{
{MessageTypeEnum.A, new TypeAMessageHandler()},
{MessageTypeEnum.B, new TypeBMessageHandler()}
};
_target = new MessageHandlerFactory(index);
In my real example there are additional dependencies, and I'd still like to find a way that lets me use Automock to provide default implementations of those. In addition, this way does not really act the way Autofac does, since it returns the same object for TypeAMessageHandler each time it's called.
来源:https://stackoverflow.com/questions/47798273/automock-how-to-unit-test-with-keyed-registrations