2014-09-11 58 views
1

如何验证使用Moq呼叫“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)); 
} 

回答

7

呼叫至Verify在起订量为ref参数进行严格的平等检查。当参数是参考类型时(如在您的示例中),仅当实际值和预期值为相同参考号argument matcher that Moq uses成功。这是因为它使用object.ReferenceEquals(expected, actual)来验证相等性。

此行为是提到在Moq Quickstart(虽然它可能是一个小更透彻):

// 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新在DoStuff中创建的List<string>的实例,根据匹配器的实现将会失败。

这显然是一个玩具例子,所以我不能建议你应该做的,但如果你修改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));