我已经在C#中为我的MVC项目编写了一个单元测试类。
测试方法如下
[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);
}
}
服务方法如下
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);
}
}
现在这个测试方法只是因为抛出的服务类而没有传递ArgumentNullException.So如何处理ArgumentNullException或如何让这个测试通过?
请任何人帮忙
答案 0 :(得分:5)
如果您要检查ArgumentNullException
是否有效(哪个:它当前不是)。然后听起来像你想要的那样:
[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);
}
答案 1 :(得分:1)
我假设:查看代码,这个单元测试不应该通过。在大多数情况下,向列表添加NULL不是预期的行为。
我看到两个选项: A)你应该为你测试metod添加一个try / catch。
try
{
_IDocumentStatusRepositoryMock.Setup(m => m.Add(documentStatus));
documentStatusService.Add(documentStatus);
}
catch (Exception )
{
Assert.Fail(); // or nothing is expected behaviour
}
B)从测试方法中删除try / catch块,这样就不会吞下异常。 (每个没有失败的测试或者Assert或者一个unhandeled异常会自动通过)
答案 2 :(得分:0)
测试ArgumentNullException
如果你删除了不明智的
catch (Exception e)
{
throw new Exception(e.Message);
}
从您要测试的代码(当前catch
丢失错误的上下文,并打破堆栈跟踪,见下文),您的测试可以像在Assert.Throws<ArgumentNullException>()
中包装调用一样简单:
[Test]
public void PassingANullEntityToAddMustThrowArgumentNullException()
{
var documentStatusService = new DocumentStatusService(...);
Assert.Throws<ArgumentNullException>(() => documentStatusService.Add(null));
}
Re:您的异常处理程序
在您的服务代码中,永远不会捕获异常并重新抛出它,因为这会丢失堆栈跟踪(例如_repository.Add(entity);
也可能抛出。)。您也不能通过抛出e.Message
来添加任何值,因为它已经在原始异常中(包含堆栈跟踪和内部异常等附加信息)
为:
catch (Exception e)
{
throw new Exception(e.Message);
}
更好:如果您捕获并重新抛出某些值,请将原始内容包装为内部异常:
catch (SqlException ex)
{
throw new Exception("Some value add here", ex);
}
或者如果您只是拦截并允许传播:
catch (SqlException)
{
// Do some logging
throw;
}
除非您添加值或处理它,否则最好让异常传播。