Expectation for exception in test, but desire to check dispose is called anyway

I am testing a demo application which is a POP3 client. The POP3 client implements IDisposable

, so I am trying to test the loop using

.

(I am 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 method verifyAll

will never be called and the test will succeed nevertheless. So...

  • What is the best way to solve this problem?
  • Is there any other way and then try to catch?

Update. I fixed it like this:

        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 is not called , seems to be a C # specification.

+2


source to share


4 answers


mockTcpClient.Setup(x => x.Dispose());

try 
{
    using (var popClient = new PopClient(null, mockTcpClient.Object))
    {

    }
}
finally 
{
    mockTcpClient.VerifyAll();
}

      



+3


source


You already discovered that actually dispose is really not if the constructor fails. But there may be other cases where you can check your mocks after an expected exception is thrown. I just do it in a TearDown test 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();
}

      

+2


source


This doesn't answer your question (as he already solved), but it's still worth it and worth posting.

[ExpectedException] is a pretty surefire way to check for exceptions. It can be error prone as the wrong string can throw an exception of the expected type, resulting in an erroneous pass. I would highly recommend you check Assert.Throws () instead :)

Better to use (you can throw an exception to return), more readable, and above all, more secure.

You can find an example here

+2


source


You seem to be testing that the injected mockTcpClient instance gets deleted 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 it / finally get cleaner than catching the Exception. Note that you do not need to delete the popClient as it is not instantiated.

+1


source







All Articles