如何验证是否调用了两个方法中的一个

本文关键字:两个 方法 一个 何验证 验证 是否 调用 | 更新日期: 2023-09-27 17:51:06

我使用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);

当然,如果您有许多重载要处理,这仍然是乏味的。

EDIT:为了好玩,这里有一个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());
}

如果你是专门测试一个特定的错误被记录,为什么不有2个测试,一个确保log.Error被调用,一个确保log.ErrorFormat被调用,我假设你可以控制哪一个是基于输入调用。

如果你仍然想要验证其中一个,你可以使用这个方法,它正是你需要的:

验证在单元测试中调用了其中一个方法或另一个方法