繁体   English   中英

如何处理NUnit中的抛出异常

[英]How to handle thrown exception in NUnit

我已经在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或如何让这个测试通过?

请任何人帮忙

如果您正在尝试检查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);
}

我假设:看看代码,这个单元测试不应该通过。 在大多数情况下,向列表添加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异常会自动通过)

测试ArgumentNullException

如果你删除了不明智的

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

从您要测试的代码(当前catch失去错误的上下文,并打破堆栈跟踪,见下文),您的测试可以像在Assert.Throws<ArgumentNullException>()包装调用一样简单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;
 }

除非您添加值或处理它,否则我最好让异常传播。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM