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
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);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With