我正在使用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
}
相同顺序,相同方法,相同参数。 Moq有可能吗?还是我需要另一个模拟框架?
答案 0 :(得分:0)
我自己找到了一个使用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);
}
我知道代码非常笨拙,尤其是字符串比较,但是暂时就足够了。