Using Moq to Test Individual Calls with Different Arguments

I try to check the values โ€‹โ€‹of arguments passed to subsequent calls of the mocked method (of the same method), but cannot find the correct approach. The following is a general example:

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(); } } 

Using a function in the installer may be an option, but it seems like I would come down to some kind of global variable to find out which argument / iteration I am checking. Perhaps I ignore the obvious in Moq?

+4
source share
2 answers

Moq distinguishes between customization and validation. Instead of VerifyAll () you can try something like

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

I have to rush home ... maybe someone has a better answer :) ... oops found a duplicate: How to check the order of a method call using Moq

+1
source

Not that I was completely wrong, or Termite is too tolerant, but the best answer is demonstrated by the following code:

 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)); } 

This shows that the setting is completely separate from the check. In some cases, this means that argument matching must be done twice: (

+1
source

Source: https://habr.com/ru/post/1334868/


All Articles