【问题标题】:Can I set-up a mock to return regardless of generic type?无论泛型类型如何,我都可以设置一个模拟返回吗?
【发布时间】:2021-06-02 01:24:26
【问题描述】:

我尝试使用单元测试进行测试的代码执行以下操作:

void DoSomething()
{
   var myTypeImplementation = _lifetimeScope.Resolve<IMyInterface<MyType>>();
   var mySecondTypeImplementation = _lifetimeScope.Resolve<IMyInterface<MySecondType>>();

   myTypeImplementation.Bar();
   mySecondTypeImplementation.Bar();
}

问题

如何通过隐式处理泛型类型来模拟 _lifetimeScope (ILifetimeScope)?

我的尝试

我有以下内容并且它可以工作,但是除了我在示例中使用的 2 种类型之外,还有更多类型,所以有一个 很多 的复制/粘贴:

        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 可能吗?但是一些我不明确处理类型的替代方法会更整洁。

【问题讨论】:

    标签: c# .net-core xunit nsubstitute


    【解决方案1】:

    选项 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();
    }
    

    【讨论】:

    • 谢谢!非常感谢您花时间回答这个问题,2 号看起来与我所追求的完全一样。我现在就试一试。
    • 是的,准确。再次感谢伙计。
    • 没问题的朋友。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多