Mat*_*els 10 c# unit-testing moq
我正在使用Moq来验证我的unittest中是否正在调用某个方法.在这种特定情况下,我想测试测试中的方法是否通过log4net记录错误.问题是,这可以通过调用log.Error或来完成log.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>()));
Run Code Online (Sandbox Code Playgroud)
现在我想起来了,它们都有一堆重载,我不介意是否也调用了任何重载(我开始怀疑这是一个很好的测试).
提前致谢.
编辑:我只是想到了一些令人讨厌的东西:
try
{
logMock.Verify(log => log.Error(It.IsAny<object>()));
}
catch (Moq.MockException ex)
{
logMock.Verify(log => log.ErrorFormat(It.IsAny<string>(), It.IsAny<object>()));
}
Run Code Online (Sandbox Code Playgroud)
也许我可以用某种扩展方法包装它...例如VerifyAny.
Sco*_*ner 12
您可以为设置标志的每个有效错误方法注册回调:
// 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);
Run Code Online (Sandbox Code Playgroud)
当然,如果你有很多重载要做,这仍然会很乏味.
编辑:为了好玩,这里有一个扩展方法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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
[TestMethod]
public void FooTest()
{
Mock<IFoo> fooMock = new Mock<IFoo>();
fooMock.Object.Bar1();
fooMock.VerifyAny(
f => f.Bar1(),
f => f.Bar2());
}
Run Code Online (Sandbox Code Playgroud)