如何验证" CallWithRef"使用Moq调用方法?
public interface ITest
{
void CallWithoutRef(string value, List<string> errors);
void CallWithRef(string value, ref List<string> errors);
}
public class Foo
{
private ITest testInterface;
public Foo(ITest testInterface)
{
this.testInterface = testInterface;
}
public void DoStuff(string value)
{
var errorList = new List<string>();
testInterface.CallWithoutRef(value, errorList);
testInterface.CallWithRef(value, ref errorList);
}
}
[TestMethod]
public void VerifyTestInterfaceCalls()
{
var expectedValue = Path.GetRandomFileName();
var mockTestInterface = new Mock<ITest>();
var foo = new Foo(mockTestInterface.Object);
foo.DoStuff(expectedValue);
mockTestInterface.Verify(x => x.CallWithoutRef(expectedValue, It.IsAny<List<string>>()));
// Test fails here:
var errorList = It.IsAny<List<string>>();
mockTestInterface.Verify(x => x.CallWithRef(expectedValue, ref errorList));
}
答案 0 :(得分:7)
Moq 4.8.0中的情况有所改善,请参阅此处的其他答案,详细了解It.Ref
!
对Moq中的Verify
的调用会对ref
个参数执行严格的相等检查。当参数是引用类型时(如示例所示),仅当实际值和期望值是相同引用时,argument matcher that Moq uses才会成功。这是因为它使用object.ReferenceEquals(expected, actual)
来验证相等性。
// ref arguments
var instance = new Bar();
// Only matches if the ref argument to the invocation is the same instance
mock.Setup(foo => foo.Submit(ref instance)).Returns(true);
在您的示例中,It.IsAny<List<string>>()
实际上最终会返回default(T)
,因此您需要将null
与List<string>
中创建的DoStuff
的新实例进行比较1}},根据匹配器的实现失败。
这显然是一个玩具示例,因此我无法建议您应该做什么,但如果您修改DoStuff
接受列表而不是创建自己的列表,则可以像这样测试:
var errorList = It.IsAny<List<string>>();
// var errorList = new List<string>(); // also works
foo.DoStuff(expectedValue, errorList);
mockTestInterface.Verify(x => x.CallWithoutRef(expectedValue, It.IsAny<List<string>>()));
mockTestInterface.Verify(x => x.CallWithRef(expectedValue, ref errorList));
答案 1 :(得分:3)
从版本4.8.0开始,现在可以使用Moq。这是链接:https://github.com/moq/moq4/issues/479
您可以像这样传递errorList
ref It.Ref<List<string>>.IsAny