无论泛型类型如何,我都可以设置一个 return 的模拟吗?
Can I set-up a mock to return regardless of generic type?
我尝试用单元测试测试的代码执行以下操作:
void DoSomething()
{
var myTypeImplementation = _lifetimeScope.Resolve<IMyInterface<MyType>>();
var mySecondTypeImplementation = _lifetimeScope.Resolve<IMyInterface<MySecondType>>();
myTypeImplementation.Bar();
mySecondTypeImplementation.Bar();
}
问题
如何通过隐式处理通用类型来模拟 _lifetimeScope
(ILifetimeScope
)?
我尝试过的
我有以下内容并且可以正常工作,但是除了我在示例中使用的 2 种类型之外,还有更多类型,所以有一个 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);
在这个设置之后,我仍然需要断言,所以现在我有每个类型的断言:
mockFirstType.Received().Bar();
mockSecondType.Received().Bar();
相反,理想的做法是将此测试编写为 Theory
并通过 Type
也许?但是一些我不显式处理类型的替代方法会更简洁。
选项 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();
}
选项 2(可能):
[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();
}
我尝试用单元测试测试的代码执行以下操作:
void DoSomething()
{
var myTypeImplementation = _lifetimeScope.Resolve<IMyInterface<MyType>>();
var mySecondTypeImplementation = _lifetimeScope.Resolve<IMyInterface<MySecondType>>();
myTypeImplementation.Bar();
mySecondTypeImplementation.Bar();
}
问题
如何通过隐式处理通用类型来模拟 _lifetimeScope
(ILifetimeScope
)?
我尝试过的
我有以下内容并且可以正常工作,但是除了我在示例中使用的 2 种类型之外,还有更多类型,所以有一个 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);
在这个设置之后,我仍然需要断言,所以现在我有每个类型的断言:
mockFirstType.Received().Bar();
mockSecondType.Received().Bar();
相反,理想的做法是将此测试编写为 Theory
并通过 Type
也许?但是一些我不显式处理类型的替代方法会更简洁。
选项 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();
}
选项 2(可能):
[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();
}