I’ve just started playing around with Moq in my unit tests, but am having an issue where the unit test is passing – and I don’t think it should be.
I have two objects, one that despatches data to a queue and another that implements INotifier which is called if the despatcher fails, they look like this (cut down for brevity):
public class EmailNotifier : INotifier
{
public void Notify(string message)
{
// sends the notification by email
}
}
public class Despatcher
{
public void Despatch(int batchNumber, INotifier failureNotifier)
{
try
{
if (batchNumber.Equals(0)) throw new InvalidOperationException("Error message");
}
catch (InvalidOperationException ex)
{
failureNotifier.Notify(ex.ToString());
throw ex;
}
}
}
I am unit testing the Despatcher to specifically verify that Notify is being called on the provided INotifier (which I’m mocking) when it fails (I’m intentionally forcing the Despatcher to fail by passing a 0 batch number). I set up my mocks like this:
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Despatcher_notifies_on_failure()
{
var mockNotifier = new Mock<EmailNotifier>();
mockNotifier.Setup(n => n.Notify(It.IsAny<string>())).Verifiable();
var despatcher = new Despatcher();
despatcher.Despatch(0, mockNotifier.Object);
mockNotifier.Verify(n => n.Notify(It.IsAny<string>()), Times.Once());
}
This passes the test fine, which is expected as a 0 batch number raises the exception which causes the INotifier to call Notify (when I step through the test everything works as expected).
So, I go on to comment out the failureNotifier.Notify(ex.ToString()) line and run the test again – passes fine? I’m not sure whether I’m setting up and verifying correctly as I’ve only been using Moq for about 2 hours now but I thought I was understanding this correctly, but this has just thrown me a bit. I expect this test to fail as I specifically want to make sure Notify is called in the event of a failure – can anyone see anything obviously wrong here? Thanks in advance for your help as always.
Your test never gets to the verification part. Why? This line
Throws exception, which is consumed by
ExpectedExceptionattribute and test ends. ThemockNotifier.Verifyline is never executed.What you want is two unit tests, instead:
.Verify). Note that you’ll have to wrap.Despatchcall intotry { } catch { }, so that exception is ignored.ExpectedException)