Reputation: 587
I'm unit testing a demo application, which is a POP3 client. The POP3 client implements IDisposable
, so I'm trying to test a using
cycle.
(I'm using nunit 2.5.2 and Moq 4.0)
/// <summary>
/// Unsuccessful construct dispose cycle, no ILogger object given.
/// Expecting ArgumentNullException. Expecting TcpClient dispose to be called.
/// </summary>
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ConstructorDispose_LoggerNull_ArgumentNullException()
{
mockTcpClient.Setup(x => x.Dispose());
using (var popClient = new PopClient(null, mockTcpClient.Object))
{
}
mockTcpClient.VerifyAll();
}
As you can see the verifyAll
method will never be invoked and the test will be successful, nonetheless. So ...
Update I fixed it like this for the moment:
mockTcpClient.Setup(x => x.Dispose());
var correctExceptionThrown = false;
try
{
using (var popClient = new PopClient(null, mockTcpClient.Object))
{
}
}
catch (ArgumentNullException)
{
correctExceptionThrown = true;
}
finally
{
mockTcpClient.VerifyAll();
}
Assert.That(correctExceptionThrown);
But dispose isn't called, seems to be the C# specification.
Upvotes: 2
Views: 3569
Reputation: 66733
You have already discovered that dispose really is not supposed to be called if the constructor fails. But there may still be other cases where you might want to to verify your mocks after an expected exception is thrown. I just do that in the test TearDown like this:
[SetUp]
public void SetUp()
{
this.mockFactory = new MockFactory(MockBehavior.Loose);
}
[TearDown]
public void TearDown()
{
this.mockFactory.VerifyAll();
}
[Test]
[ExpectedException(typeof(NoBananasException))]
public void EatThrowsIfNoBananasAvailable
{
var bananaProvider = this.mockFactory.Create<IBananaProvider>();
bananaProvider.SetUp(bp => bp.IsBananaAvailable).Returns(false).Verifiable();
var monkey = new Monkey(bananaProvider.Object);
monkey.Eat();
}
Upvotes: 2
Reputation: 23365
This doesn't answer your question (as it's already solved), but it's relevant and worth posting anyway.
[ExpectedException] is a pretty ropey way to test exceptions. It can be error prone, as the wrong line can trigger an exception of the expected type resulting in an erroneous pass. I would strongly advocate that you check out Assert.Throws() instead :)
It's nicer to use (you can query the returned exception), more readable and, above all, safer.
Upvotes: 2
Reputation: 144136
You seem to be testing that the injected mockTcpClient instance is disposed even if the constructor throws an exception, in which case this should work:
mockTcpClient.Setup(x => x.Dispose());
try
{
var popClient= new PopClient(null, mockTcpClient.Object);
}
finally
{
mockTcpClient.VerifyAll();
}
EDIT: Actually, try/finally would be cleaner than catching Exception. Note that you don't need to dispose popClient since no instance is created.
Upvotes: 1
Reputation: 9951
mockTcpClient.Setup(x => x.Dispose());
try
{
using (var popClient = new PopClient(null, mockTcpClient.Object))
{
}
}
finally
{
mockTcpClient.VerifyAll();
}
Upvotes: 4