Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle thrown exception in NUnit

I have written a unit test class in C# for my MVC project.

The Test Method is following

 [Test]
    public void To_Add_DocumentStatusIsNull_ThrowsInvalidOperationException_ServiceTest()
    {
        try
        {

        _IDocumentStatusRepositoryMock = new Mock<IDocumentStatusRepository>();
        _unitOfWorkMock = new Mock<IUnitOfWork>();

        DocumentStatusService documentStatusService = new  
         DocumentStatusService(_unitOfWorkMock.Object,  
          _IDocumentStatusRepositoryMock.Object); 

        DocumentStatus documentStatus;
        documentStatus = null;

        _IDocumentStatusRepositoryMock.Setup(m => m.Add(documentStatus));
        documentStatusService.Add(documentStatus);

        Assert.Pass();

        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
    }

And the Service Method is following

   public virtual void Add(TEntity entity)
    {
        try
        {

        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        }
        _repository.Add(entity);

        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
    }

Now This test method only not passed due to the service class thrown ArgumentNullException.So how to handle the ArgumentNullException or How to make this test pass?

Please anybody help

like image 270
Md Aslam Avatar asked Sep 29 '14 10:09

Md Aslam


2 Answers

If you are trying to check that the ArgumentNullException is working (which: it isn't currently). then it sounds like you want:

[Test, ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null.
Parameter name: entity")]
public void To_Add_DocumentStatusIsNull_ThrowsInvalidOperationException_ServiceTest()
{
    _IDocumentStatusRepositoryMock = new Mock<IDocumentStatusRepository>();
    _unitOfWorkMock = new Mock<IUnitOfWork>();

    DocumentStatusService documentStatusService = new  
     DocumentStatusService(_unitOfWorkMock.Object,  
      _IDocumentStatusRepositoryMock.Object); 

    DocumentStatus documentStatus;
    documentStatus = null;

    _IDocumentStatusRepositoryMock.Setup(m => m.Add(documentStatus));
    documentStatusService.Add(documentStatus);
}

...

public virtual void Add(TEntity entity)
{
    if (entity == null)
    {
        throw new ArgumentNullException("entity");
    }
    _repository.Add(entity);
}
like image 116
Marc Gravell Avatar answered Sep 20 '22 12:09

Marc Gravell


Testing for the ArgumentNullException

If you remove the ill-advised

catch (Exception e)
{
   throw new Exception(e.Message);
}

from your code to be tested (The current catch loses context of the error, and breaks the stack trace, see below), your test can be as simple as wrapping the invocation in an Assert.Throws<ArgumentNullException>():

[Test]
public void PassingANullEntityToAddMustThrowArgumentNullException()
{
    var documentStatusService = new  DocumentStatusService(...); 
    Assert.Throws<ArgumentNullException>(() =>  documentStatusService.Add(null));
}

Re: Your Exception Handler

In your service code, never catch an exception and rethrow it as you've done, as this will lose the stack trace (e.g. _repository.Add(entity); could throw as well.). You also aren't adding any value by throwing e.Message as this is already in the original exception (with additional info like stack trace and inner exception)

Bad:

  catch (Exception e)
  {
      throw new Exception(e.Message);
  }

Better: If you do catch and rethrow with some value, wrap the original as an inner exception:

 catch (SqlException ex)
 {
    throw new Exception("Some value add here", ex);
 }

or if you are just intercepting and allow to propagate:

 catch (SqlException)
 {
    // Do some logging
    throw;
 }

Best to me would to let the exception propagate, unless you either adding value, or handling it.

like image 34
StuartLC Avatar answered Sep 16 '22 12:09

StuartLC