验证使用Moq调用的通用方法

本文关键字:方法 Moq 验证 调用 | 更新日期: 2023-09-27 18:01:33

我在验证使用Moq.Mock.Verify调用IInterface.SomeMethod<T>(T arg)的模拟时遇到麻烦。

我可以验证该方法是在使用It.IsAny<IGenericInterface>()It.IsAny<ConcreteImplementationOfIGenericInterface>()的"标准"接口上调用的,并且我没有麻烦使用It.IsAny<ConcreteImplementationOfIGenericInterface>()验证泛型方法调用,但我无法验证使用It.IsAny<IGenericInterface>()调用泛型方法-它总是说该方法未被调用并且单元测试失败。

下面是我的单元测试:

public void TestMethod1()
{
    var mockInterface = new Mock<IServiceInterface>();
    var classUnderTest = new ClassUnderTest(mockInterface.Object);
    classUnderTest.Run();
    // next three lines are fine and pass the unit tests
    mockInterface.Verify(serviceInterface => serviceInterface.NotGenericMethod(It.IsAny<ConcreteSpecificCommand>()), Times.Once());
    mockInterface.Verify(serviceInterface => serviceInterface.NotGenericMethod(It.IsAny<ISpecificCommand>()), Times.Once());
    mockInterface.Verify(serviceInterface => serviceInterface.GenericMethod(It.IsAny<ConcreteSpecificCommand>()), Times.Once());
    // this line breaks: "Expected invocation on the mock once, but was 0 times"
    mockInterface.Verify(serviceInterface => serviceInterface.GenericMethod(It.IsAny<ISpecificCommand>()), Times.Once());
}

下面是我要测试的类:

public class ClassUnderTest
{
    private IServiceInterface _service;
    public ClassUnderTest(IServiceInterface service)
    {
        _service = service;
    }
    public void Run()
    {
        var command = new ConcreteSpecificCommand();
        _service.GenericMethod(command);
        _service.NotGenericMethod(command);
    }
}

这是我的IServiceInterface:

public interface IServiceInterface
{
    void NotGenericMethod(ISpecificCommand command);
    void GenericMethod<T>(T command);
}

下面是我的接口/类继承层次:

public interface ISpecificCommand
{
}
public class ConcreteSpecificCommand : ISpecificCommand
{
}

验证使用Moq调用的通用方法

这是Moq 4.0.10827(当前发布版本)中的已知问题。请参阅GitHub https://github.com/Moq/moq4/pull/25上的讨论。我已经下载了它的dev分支,编译并引用了它,现在你的测试通过了。

我要即兴发挥。由于GenericMethod<T>要求提供T参数,是否可以这样做:

mockInterface.Verify(serviceInterface => serviceInterface.GenericMethod(It.Is<object>(x=> typeof(ISpecificCommand).IsAssignableFrom(x.GetType()))), Times.Once());