使用 Moq Verify 防止长 Visual Studio 测试跟踪输出
Prevent long Visual Studio test trace output with Moq Verify
我想使用 Moq 的 Verify 方法验证是否调用了一个方法。我的部分测试涉及大量循环,在此期间,除了我要验证的方法之外,我的模拟对象上的许多其他方法也被调用。
如果验证断言失败,在相关测试的 Visual Studio 测试资源管理器输出窗格中,除了有关验证失败原因的错误消息外,还列出了所有其他调用在模拟对象上制作,延伸到 1000 行。这使得测试资源管理器 window 在加载完整的异常详细信息之前变得无法使用,这有时可能需要几分钟。
有什么方法可以防止 Moq 列出所有其他已执行的调用?我只关心验证是否失败
复制问题的人为代码:
public interface IMyInterface
{
void Foo();
void Bar();
void FooBar();
}
[TestClass]
public class TestClass1
{
[TestMethod]
public void TestMethod1()
{
using (var mock = AutoMock.GetLoose())
{
var myInterfaceMock = mock.Mock<IMyInterface>();
var myInterfaceObj = myInterfaceMock.Object;
for (var i = 0; i < 1000; i++)
{
myInterfaceObj.Foo();
myInterfaceObj.Bar();
}
myInterfaceMock.Verify(x => x.FooBar(), Times.Once());
}
}
}
测试资源管理器输出,持续 1000 行(对于大尺寸、高 DPI 屏幕感到抱歉):
非常感谢
这不是使用 Verify()
的直接答案,否则会阻止 Moq 列出所有其他已执行的调用。
它使用 Callback
来计算方法 FooBar
被调用的次数。不知道你会不会喜欢这样的方式?
[TestMethod]
public void TestMethod1()
{
int expectedCount = 1;
int actualCount = 0;
using (var mock = AutoMock.GetLoose())
{
var myInterfaceMock = mock.Mock<IMyInterface>();
var myInterfaceObj = myInterfaceMock.Object;
myInterfaceMock.Setup(mi => mi.FooBar()).Callback(() => actualCount++);
for (var i = 0; i < 1000; i++)
{
myInterfaceObj.Foo();
myInterfaceObj.Bar();
}
Assert.AreEqual( expectedCount, actualCount, $"Expected invocation on the mock was '{expectedCount}' times, but was called '{actualCount}' times");
}
}
Output:
Assert.AreEqual failed. Expected:<1>. Actual:<0>. Expected
invocation on the mock was '1' times, but was called '0' times
Verify 在条件失败时抛出异常,所以这看起来像是简单地捕获异常、解析消息然后用你想要的消息部分使测试失败的情况。考虑到消息的当前格式,这是微不足道的:
var myInterfaceMock = new Mock<IMyInterface>();
var myInterfaceObj = myInterfaceMock.Object;
for (var i = 0; i < 1000; i++)
{
myInterfaceObj.Foo();
myInterfaceObj.Bar();
}
try
{
myInterfaceMock.Verify(x => x.FooBar(), Times.Once());
}
catch (MockException me)
{
throw new Exception(me.Message.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)[0]);
}
结果:
你如何通过测试取决于你,我刚刚作为 MVP 抛出了一个新的异常。
如果是我,我会把它放到扩展方法中以保持测试干净。您可能必须执行其中几个操作才能处理 Verify 重载。
我想使用 Moq 的 Verify 方法验证是否调用了一个方法。我的部分测试涉及大量循环,在此期间,除了我要验证的方法之外,我的模拟对象上的许多其他方法也被调用。
如果验证断言失败,在相关测试的 Visual Studio 测试资源管理器输出窗格中,除了有关验证失败原因的错误消息外,还列出了所有其他调用在模拟对象上制作,延伸到 1000 行。这使得测试资源管理器 window 在加载完整的异常详细信息之前变得无法使用,这有时可能需要几分钟。
有什么方法可以防止 Moq 列出所有其他已执行的调用?我只关心验证是否失败
复制问题的人为代码:
public interface IMyInterface
{
void Foo();
void Bar();
void FooBar();
}
[TestClass]
public class TestClass1
{
[TestMethod]
public void TestMethod1()
{
using (var mock = AutoMock.GetLoose())
{
var myInterfaceMock = mock.Mock<IMyInterface>();
var myInterfaceObj = myInterfaceMock.Object;
for (var i = 0; i < 1000; i++)
{
myInterfaceObj.Foo();
myInterfaceObj.Bar();
}
myInterfaceMock.Verify(x => x.FooBar(), Times.Once());
}
}
}
测试资源管理器输出,持续 1000 行(对于大尺寸、高 DPI 屏幕感到抱歉):
非常感谢
这不是使用 Verify()
的直接答案,否则会阻止 Moq 列出所有其他已执行的调用。
它使用 Callback
来计算方法 FooBar
被调用的次数。不知道你会不会喜欢这样的方式?
[TestMethod]
public void TestMethod1()
{
int expectedCount = 1;
int actualCount = 0;
using (var mock = AutoMock.GetLoose())
{
var myInterfaceMock = mock.Mock<IMyInterface>();
var myInterfaceObj = myInterfaceMock.Object;
myInterfaceMock.Setup(mi => mi.FooBar()).Callback(() => actualCount++);
for (var i = 0; i < 1000; i++)
{
myInterfaceObj.Foo();
myInterfaceObj.Bar();
}
Assert.AreEqual( expectedCount, actualCount, $"Expected invocation on the mock was '{expectedCount}' times, but was called '{actualCount}' times");
}
}
Output:
Assert.AreEqual failed. Expected:<1>. Actual:<0>. Expected invocation on the mock was '1' times, but was called '0' times
Verify 在条件失败时抛出异常,所以这看起来像是简单地捕获异常、解析消息然后用你想要的消息部分使测试失败的情况。考虑到消息的当前格式,这是微不足道的:
var myInterfaceMock = new Mock<IMyInterface>();
var myInterfaceObj = myInterfaceMock.Object;
for (var i = 0; i < 1000; i++)
{
myInterfaceObj.Foo();
myInterfaceObj.Bar();
}
try
{
myInterfaceMock.Verify(x => x.FooBar(), Times.Once());
}
catch (MockException me)
{
throw new Exception(me.Message.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)[0]);
}
结果:
你如何通过测试取决于你,我刚刚作为 MVP 抛出了一个新的异常。 如果是我,我会把它放到扩展方法中以保持测试干净。您可能必须执行其中几个操作才能处理 Verify 重载。