【问题标题】:Check that two different methods call the same methods on mocked object检查两个不同的方法在模拟对象上调用相同的方法
【发布时间】:2020-02-20 14:40:31
【问题描述】:

我使用 Moq 作为模拟框架。我有一种情况,我想执行两种不同的方法,它们都调用方法和接口。我想确保这两种方法在我的界面上以相同的顺序和相同的参数调用完全相同的方法。为了说明,这里是代码:

[TestMethod]
public void UnitTest()
{
var classToTest = new ClassToTest();
Mock<IMyInterface> mock1 = new Mock<IMyInterface>();
// Setup the mock
Mock<IMyInterface> mock2 = new Mock<IMyInterface>();
// Setup the mock


classToTest.MethodToTest(mock1.Object);
classToTest.DifferentMethodToTest(mock2.Object);

// here I need help:
mock1.Verify(theSameMethodsAsMock2);
}

例如,如果IMyInterface 有两个方法Method1(int i)Method2(string s),如果MethodToTest 具有结构,则测试应该通过

void MethodToTest(IMyInterface x)
{
x.Method1(42);
x.Method2("example");
x.Method1(0);
}

DifferentMethodToTest 看起来像这样:

void MethodToTest(IMyInterface x)
{
int a = 10 + 32;
x.Method1(a);
string s = "examples";
x.Method2(s.Substring(0, 7));
x.Method1(0);
// might also have some code here that not related to IMyInterface at all, 
// e.g. calling methods in other classes and so on
}

相同的顺序,相同的方法,相同的参数。起订量可以吗?还是我需要另一个模拟框架?

【问题讨论】:

  • 你需要从方法返回某种结果而不是 void,这样你就可以检查两者是否执行相同。
  • 这有关系吗?您可以使用回调来跟踪方法调用。 stackoverflow.com/questions/24027301/…
  • 当然可以使用验证和回调,但问题的核心是你要验证两个方法做同样的事情。那你为什么不把这个逻辑转移到一种方法中呢?
  • @CodeCaster:我重构了一个巨大的方法。我想确保我没有通过重构引入任何错误。
  • 也许可以查看Capture.In然后检查订单...

标签: c# unit-testing moq


【解决方案1】:

我自己找到了一个使用InvocationAction的解决方案:

[TestMethod]
public void Test()
{
var classToTest = new ClassToTest();

var methodCalls1 = new List<string>();
var invocationAction1 = new InvocationAction((ia) =>
{
     string methodCall = $"{ia.Method.Name} was called with parameters {string.Join(", ", ia.Arguments.Select(x => x?.ToString() ?? "null"))}";
     methodCalls1.Add(methodCall);
});
Mock<IMyInterface> mock1 = new Mock<IMyInterface>();
mock1.Setup(x => x.Method1(It.IsAny<int>())).Callback(invocationAction1);
mock1.Setup(x => x.Method2(It.IsAny<string>())).Callback(invocationAction1);

// Same for mock2 ...


classToTest.MethodToTest(mock1.Object);
classToTest.DifferentMethodToTest(mock2.Object);

CollectionAssert.AreEqual(methodCalls1, methodCalls2);
}

我知道代码很笨拙,尤其是字符串比较,但暂时够用了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多