Code I'm attempting to test with unit tests does the following:
void DoSomething()
{
var myTypeImplementation = _lifetimeScope.Resolve<IMyInterface<MyType>>();
var mySecondTypeImplementation = _lifetimeScope.Resolve<IMyInterface<MySecondType>>();
myTypeImplementation.Bar();
mySecondTypeImplementation.Bar();
}
How can I mock _lifetimeScope
(ILifetimeScope
) by handling the generic type implicitly?
I have the following and it works, but there are many more types than just the 2 I've used in my example, so there's a lot of copy/paste:
var mockFirstType = Substitute.For<IMyInterface<MyType>>();
_mockLifetimeScope.Resolve<IMyInterface<MyType>().Returns(mockFirstType);
var mockSecondType = Substitute.For<IMyInterface<MySecondType>>();
_mockLifetimeScope.Resolve<IMyInterface<MySecondType>().Returns(mockSecondType);
After this set-up, I still need to assert, so now I have an assertion per type:
mockFirstType.Received().Bar();
mockSecondType.Received().Bar();
Instead, the ideal would be to write this test as a Theory
and pass a Type
maybe? But some alternative approach where I don't handle types explicitly would be a lot neater.
Option 1:
[Fact]
public void TestMethod()
{
var myFirstVerificationCallback = GetVerificationCallback<MyType>();
var mySecondVerificationCallback = GetVerificationCallback<MySecondType>();
var myThirdVerificationCallback = GetVerificationCallback<MyThirdType>();
myFirstVerificationCallback();
mySecondVerificationCallback();
myThirdVerificationCallback();
}
private Action GetVerificationCallback<T>()
{
var typeMock = Substitute.For<IMyInterface<T>>();
_mockLifetimeScope
.Resolve<IMyInterface<T>>()
.Returns(typeMock);
return () => typeMock
.Received()
.Bar();
}
Option 2 (maybe):
[Theory]
[InlineData(typeof(MyType))]
[InlineData(typeof(MySecondType))]
[InlineData(typeof(MyThirdType))]
public void TestMethod(Type typeParameterType)
{
var serviceTypeToMock = typeof(IMyInterface<>).MakeGenericType(typeParameterType);
var substitution = Substitute.For(new Type[] {serviceTypeToMock}, Array.Empty<object>());
_mockLifetimeScope
.Resolve(serviceTypeToMock)
.Returns(substitution);
(substitution.Received() as dynamic).Bar();
}