Search code examples
c#unit-testingmockingtddmoq

What is It.IsAny and what is It.Is in Unit mock testing


There are many questions that have been already asked on this but I think I need something more basic that could clear this concept as I am beginner in TDD. I can't go forward till then.

Could you please go through following test method and explain if I have wrong understanding:

[Test]
public void ShouldSearch()
{
         var ColumnList = new List<Column>();
    

The below line means that I am mocking object.

But what this It.IsAny<>() means here?

 this.ColumnServiceMock.Setup(x => x.GetColumn(It.IsAny<Context>(), It.IsAny<Column>()))
                       .Returns(ColumnList);

 var result = this.getColouminfo.GetFinalRecords(this.context, this.gridColumn);

 this.ColumnServiceMock.Verify(x => x.GetColumn(It.Is<Context>(y => y == this.context),
 It.Is<Column>(y => y.Id == 2)), Times.Once);

  Assert.AreEqual(1, result.Data.Count, "Not equal");

  Assert.IsTrue(result.Data.Success, "No success");

Solution

  • It.IsAny<T> is checking that the parameter is of type T, it can be any instance of type T. It's basically saying, I don't care what you pass in here as long as it is type of T.

    this.ColumnServiceMock
        .Setup(x => x.GetColumn(It.IsAny<Context>(), It.IsAny<Column>()))
        .Returns(ColumnList);
    

    The above is saying whenever the GetColumn method is called with any parameters (as long as they are type of Context and Column respectively), return the ColumnList.

    It.Is<T> allows you to inspect what was passed in and determine if the parameter that was passed in meets your needs.

    this.ColumnServiceMock
        .Verify(
            x => x.GetColumn(It.Is<Context>(y => y == this.context), It.Is<Column>(y => y.Id == 2)),
            Times.Once);
    

    The above is asserting that the GetColumn method was called exactly once with the Context parameter equal to this.Context and a Column parameter whose Id property equals 2.

    Edit: Revisiting this answer years later with some more knowledge.

    this.ColumnServiceMock
        .Verify(
            x => x.GetColumn(It.Is<Context>(y => y == this.context), It.Is<Column>(y => y.Id == 2)),
            Times.Once);
    

    can be shortened to

    this.ColumnServiceMock
        .Verify(
            x => x.GetColumn(this.context, It.Is<Column>(y => y.Id == 2)),
            Times.Once);
    

    You don't need to use It.Is to check for reference equality, you can just pass the object directly.