2011-01-10 56 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)); 
    } 

这说明该设置与验证完全分离。在某些情况下,这意味着参数匹配必须执行两次:(