2011-01-10 75 views
4

我想驗證傳遞給隨後的模擬方法調用(同一方法)的參數值,但找不到有效的方法。一個普通的例子如下:使用Moq驗證具有不同參數的單獨調用

public class Foo 
{ 
    [Dependency] 
    public Bar SomeBar 
    { 
     get; 
     set; 
    } 

    public void SomeMethod() 
    { 
     this.SomeBar.SomeOtherMethod("baz"); 
     this.SomeBar.SomeOtherMethod("bag"); 
    } 
} 

public class Bar 
{ 
    public void SomeOtherMethod(string input) 
    { 
    } 
} 

public class MoqTest 
{ 
    [TestMethod] 
    public void RunTest() 
    { 
     Mock<Bar> mock = new Mock<Bar>(); 
     Foo f = new Foo(); 
     mock.Setup(m => m.SomeOtherMethod(It.Is<string>("baz"))); 
     mock.Setup(m => m.SomeOtherMethod(It.Is<string>("bag"))); // this of course overrides the first call 
     f.SomeMethod(); 
     mock.VerifyAll(); 
    } 
} 

在安裝使用功能可能是一種選擇,但後來好像我會減少到某種全局變量的知道我驗證這論點/迭代。也許我忽略了Moq框架中的明顯內容?

回答

1

Moq區分設置和驗證。相反VerifyAll(),你可以嘗試這樣

mock.Verify(m => m.SomeOtherMethod(It.Is("baz")), Times.Exactly(1)); mock.Verify(m => m.SomeOtherMethod(It.Is("bag")), Times.Exactly(1));

我已經給趕回家......也許別人有更好的答案:) ......哎呀發現重複: How to test method call order with Moq

+0

這不完全是我想要的,因爲它不能確保以所需的特定順序調用該方法,並且鏈接的帖子基本上解釋了那裏這並不是Moq的直接支持,但我同意這可能是最好的選擇。 – Thermite 2011-01-11 01:48:17

1

不,我是完全不正確或白蟻太寬容, 但更好的答案是由下面的代碼演示:

public interface IA 
    { 
     int doA(int i); 
    } 
    public class B 
    { 
     private IA callee; 
     public B(IA callee) 
     { 
      this.callee = callee; 
     } 
     public int doB(int i) 
     { 
      Console.WriteLine("B called with " + i); 
      var res = callee.doA(i); 
      Console.WriteLine("Delegate returned " + res); 
      return res; 
     } 
    } 
    [Test] 
    public void TEST() 
    { 
     var mock = new Mock<IA>(); 
     mock.Setup(a => a.doA(It.IsInRange(-5, 100, Range.Exclusive))).Returns((int i) => i * i); 
     var b = new B(mock.Object); 
     for (int i = 0; i < 10; i++) 
     { 
      b.doB(i); 
     } 

     mock.Verify(a => a.doA(It.IsInRange(0, 4, Range.Inclusive)), Times.Exactly(5)); 
     mock.Verify(a => a.doA(It.IsInRange(5, 9, Range.Inclusive)), Times.Exactly(5)); 
     mock.Verify(a => a.doA(It.Is<int>(i => i < 0)), Times.Never()); 
     mock.Verify(a => a.doA(It.Is<int>(i => i > 9)), Times.Never()); 
     mock.Verify(a => a.doA(It.IsInRange(3, 7, Range.Inclusive)), Times.Exactly(5)); 

     // line below will fail 
     // mock.Verify(a => a.doA(It.IsInRange(3, 7, Range.Inclusive)), Times.Exactly(7)); 
    } 

這說明該設置與驗證完全分離。在某些情況下,這意味着參數匹配必須執行兩次:(