Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq - using It.Is<> when passing parameters vs not using it

In which cases it is crucial to use It.Is<> syntax when passing parameter to Moq setup, instead of retrieving the value of such parameter separately, and then passing it in a "plain" way? So far my testing needs could have been limited, but I did not come across a need to use It.Is<> which could not be defined outside of the mock.Setup? It.Is<> looks very popular when I look through sources, also for such basic examples, so I wonder what would be the advantage. Below is simple example for brevity, but also with other cases I came across it did not make any difference. I mean:

mockRepo.Setup(m =>m.GetAllReadingsOn
(latestDate)
.Returns(_filteredReadings);

vs.

mockRepo.Setup(m => m.GetAllReadingsOn
(It.Is<DateTime>(d => d ==_latestDate)))
.Returns(_filteredReadings);
like image 949
Turo Avatar asked Apr 22 '26 21:04

Turo


1 Answers

I would always use the first approach as it is shorter. There's one exception: reference types which cannot be compared against because the method under test creates them. In this case you will need to compare property by property to ensure that the method created and passed a correct reference type:

mockRepo.Setup(m => m.GetAllReadingsOn(It.Is<SomeComplexObject>(x => 
    x.Foo == "foo" && 
    x.Bar == "bar" && 
    x.Baz == 123)))
.Returns(_filteredReadings);

This being said using this approach with value types such as DateTimes is a complete waste of keystrokes.


As requested in the comments section here's a basic example when the first approach will not work. Suppose we want to test the following method:

public SomeResult FooBarBaz()
{
    var myModel = new SomeComplexObject();
    myModel.Foo = "foo";
    myModel.Bar = "bar";
    myModel.Baz = 123;
    var result = repository.GetTheResult(myModel);

    return result;
}

Now obviously if you try to write the following test it will fail miserably:

// arrange
var sut = new Sut();
var myModel = new SomeComplexObject();
myModel.Foo = "foo";
myModel.Bar = "bar";
myModel.Baz = 123;
var expected = new SomeResult();
mockRepo
    .Setup(m => m.GetAllReadingsOn(myModel)
    .Returns(expected);

// act
var actual = sut.FooBarBaz();

// assert
Assert.AreEqual(expected, actual);
like image 117
Darin Dimitrov Avatar answered Apr 24 '26 11:04

Darin Dimitrov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!