A method call twice with different values. Testing modules using MOQ

I want to test a construct that calls a method inside it twice to get two different values

public class stubhandler { public stubhandler() { string codetext = model.getValueByCode(int a,string b); // 1,"High" result Canada string datatext = model.getValueByCode(int a,string b); // 10, "Slow" result Motion } } 

To check above, I use the unit test class

 [TestMethod] public void StubHandlerConstructor_Test() { Mock<Model> objMock = new Mock<>(Model); objMock.Setup(m => m.getValueByCode(It.IsAny<int>,It.IsAny<string>)).Returns("Canada"); objMock.Setup(m => m.getValueByCode(It.IsAny<int>,It.IsAny<string>)).Returns("Motion"); stubhandler classstubhandler = new stubhandler(); } 

The above method passes, but codetextext and datatext contain the same Motion value I want them to set

 codetext = Canada datatext = Motion 

How can i achieve this?

I tried objMock.VerifyAll() , which failed the test

+4
source share
2 answers

When using MOQ 4, you can use SetupSequence, otherwise it can be done using lambda

Using SetupSequence is pretty clear.

Using lambda is not too dirty. The important point is not that the return value is set when the installation is declared . If you just used

 mockFoo.Setup(mk => mk.Bar()).Returns(pieces[pieceIdx++]); 

the setting will always return parts [0]. Using lambda, evaluation is deferred until Bar () is called.

 public interface IFoo { string Bar(); } public class Snafu { private IFoo _foo; public Snafu(IFoo foo) { _foo = foo; } public string GetGreeting() { return string.Format("{0} {1}", _foo.Bar(), _foo.Bar()); } } [TestMethod] public void UsingSequences() { var mockFoo = new Mock<IFoo>(); mockFoo.SetupSequence(mk => mk.Bar()).Returns("Hello").Returns("World"); var snafu = new Snafu(mockFoo.Object); Assert.AreEqual("Hello World", snafu.GetGreeting()); } [TestMethod] public void NotUsingSequences() { var pieces = new[] { "Hello", "World" }; var pieceIdx = 0; var mockFoo = new Mock<IFoo>(); mockFoo.Setup(mk => mk.Bar()).Returns(()=>pieces[pieceIdx++]); var snafu = new Snafu(mockFoo.Object); Assert.AreEqual("Hello World", snafu.GetGreeting()); } 
+4
source

Moq documentation says that you can simulate something like sequential returns using the Callback method:

 var values = new [] { "Canada", "Motion" }; int callNumber = 0; mock.Setup(m => m.getValueByCode(It.IsAny<int>(), It.IsAny<string>())) .Returns((i,s) => values[callNumber]) .Callback(() => callNumber++); 

This will do the trick, but this is not the most elegant solution. Matt Hamilton offers much better on his blog, with clever use of the lineup:

 var values = new Queue<string> { "Canada", "Motion" }; mock.Setup(m => m.getValueByCode(It.IsAny<int>(), It.IsAny<string>())) .Returns(() => values.Dequeue()); 

Calling mock.Object.getValueByCode twice will produce the lines "Canada" and "Motion" respectively.

+2
source

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


All Articles