c# - 如何验证是否调用了两种方法中的一种?

标签 c# unit-testing moq

我正在使用 Moq 来验证是否在我的单元测试中调用了一个方法。在这种特定情况下,我想测试被测方法是否通过 log4net 记录错误。问题是,这可以通过调用 log.Errorlog.ErrorFormat 来完成。两者都可以。

我如何验证这一点?我只知道如何验证他们都被调用了。

var logMock = new Mock<ILog>();

var myClass = new MyClass(logMock.Object);

myClass.MyMethod();

logMock.Verify(log => log.Error(It.IsAny<object>()));
logMock.Verify(log => log.ErrorFormat(It.IsAny<string>(), It.IsAny<object>()));

现在我想起来了,它们都有一堆重载,我不介意是否调用任何一个重载(我开始怀疑这是一个很好的测试)。

提前致谢。

编辑:我只是想到了一些讨厌的事情:

try
{
    logMock.Verify(log => log.Error(It.IsAny<object>()));
}
catch (Moq.MockException ex)
{
    logMock.Verify(log => log.ErrorFormat(It.IsAny<string>(), It.IsAny<object>()));
}

也许我可以用某种扩展方法来包装它……例如VerifyAny.

最佳答案

您可以为每个设置标志的有效错误方法注册一个回调:

// Arrange
bool errorFlag = false;
logMock
    .Setup(l => l.Error(It.IsAny<object>()))
    .Callback((object o) => errorFlag = true);

/* repeat setup for each logMock method */

// Act
myClass.MyMethod();

// Assert
Assert.IsTrue(errorFlag);

当然,如果您要处理许多重载,这仍然会很乏味。

编辑:为了好玩,这里有一个 Mock<T>.VerifyAny 的扩展方法。 :

public static class MockExtensions
{
    public static void VerifyAny<T>(this Mock<T> mock, params Expression<Action<T>>[] expressions)
        where T: class
    {
        List<MockException> exceptions = new List<MockException>();
        bool success = false;
        foreach (var expression in expressions)
        {
            try
            {
                mock.Verify(expression);
                success = true;
                break;
            }
            catch (MockException ex)
            {
                exceptions.Add(ex);
            }
        }

        if (!success)
        {
            throw new AggregateException("None of the specified methods were invoked.", exceptions);
        }
    }
}

用法:

[TestMethod]
public void FooTest()
{
    Mock<IFoo> fooMock = new Mock<IFoo>();
    fooMock.Object.Bar1();

    fooMock.VerifyAny(
        f => f.Bar1(),
        f => f.Bar2());
}

关于c# - 如何验证是否调用了两种方法中的一种?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14248735/

相关文章:

c# - 更高效的数据库访问

php - 为什么 phpunit 不在模拟类中运行 __destruct() 以及如何强制运行它?

c# - .NET 单元测试 - 带有 MVC 的 Moq/xUnit 框架,未返回预期结果

entity-framework-core - .NET MAUI 集成测试 - FileNotFoundException : Could not load file or assembly Microsoft. Maui.Essentials

C# 在 Control 的生命周期中 Site (ISite) 不为空?

c# - CheckBox IsChecked 和 IsMouseOver

c# - 过滤列表对象的通用方法

c# - 使用事件和委托(delegate)对类进行单元测试

java - 对使用 UDP 套接字的代码进行单元测试的推荐方法是什么?

c# - 使用 AutoFac 和 AutoMock 模拟 CloudBlobClient