2014-09-11 18 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));