Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking a method with conditional arguments using Moq

I have a class that I am unit testing, to verify a specific exception condition is handled gracefully. To this end, I mock the method that is called internally to throw the exception.

my mocking setup looks like this:

fr.CallBase = true;
fr.Setup(m => m.PutFile(It.IsAny<IFileConnection>(), It.IsAny<string>(), It.IsAny<string>()))
    .Throws(new System.IO.IOException("Test Exception", new System.Net.Sockets.SocketException()));

this does exactly what I want it to do.

Now, however, I want to test continuity by only throwing an exception for a specific value. I thought it should look like this:

fr.Setup(m => m.PutFile(It.IsAny<IFileConnection>(), It.Is<string>(a => a == "foo2.txt"), It.IsAny<string>()))
    .Throws(new System.IO.IOException("Test Exception", new System.Net.Sockets.SocketException()));

...but this doesn't seem to work. What am I doing wrong?

Per request, the entire test:

[Test]
public void ManualRouteInterruptedInDownloadContinuesOn()
{
    var firstRoute = this.UnitOfWork.GetFirstRoute();
    Route r = this.UnitOfWork.GetRouteByID(firstRoute.RouteID);
    r.RegExMatch = "^foo\\d.txt$";
    r.Manual = true;
    r.NotifyOfNewFiles = "[email protected]";
    this.UnitOfWork.Save();

    var fr = new Mock<ManualRouting>(r.RouteID);
    fr.CallBase = true;
    fr.Setup(m => m.GetFile(It.IsAny<IFileConnection>(), It.Is<string>(a => a == "foo2.txt"), It.IsAny<string>()))
        .Throws(new System.IO.IOException("Test Exception", new System.Net.Sockets.SocketException()));

    fr.Object.ExecuteRoute(firstRoute.RouteID);
    Assert.IsTrue(fr.Object.Errors.Count == 1);
    Assert.IsTrue(fr.Object.Matches.Count == 3);
}
like image 523
Jeremy Holovacs Avatar asked Apr 30 '12 19:04

Jeremy Holovacs


1 Answers

There was someone who suggested in comments that I should try

It.Is<string>(a => Equals(a, "foo2.txt"))

He cited some oddness with generics. I don't know if it had anything to do with generics, but this change did in fact work. Since the poster deleted his comment, I am making the answer in his stead.

like image 84
Jeremy Holovacs Avatar answered Oct 07 '22 11:10

Jeremy Holovacs