如何在try catch块中编写C#单元测试以获得正确的代码覆盖率

时间:2018-05-09 18:24:41

标签: c# unit-testing nunit

我有以下代码:

public class MyControllerClass : ApiController  
{  
   private readonly IManager _manager;

   public MyControllerClass(IManager manager)
   {
     this._manager = manager;
   }

   pubic async Task<IHttpActionResult> GetRequest()  
   {  
     try  
       {  
         await this._manager.GetRequest();  
         return this.ok();  
       }  
     catch (Exception ex)  
      {  
         this.logger.Error("Error message", ex);  
         throw this.HTTPResponseException("Request failed message", ex);   
      }   
   }
} 

public class ManagerFake : IManagerFake  
{  
    public Task GetRequest()  
    {  
        return Task.FromResult(true);  
    }  
}     

我正在使用NUnit进行单元测试。对于单元测试,我在我的IOC容器中注册了一个FakeManager类,它包含GetResult()方法,并在执行时简单地返回Task.FromResult(true)。这允许执行try块中的逻辑,从而满足该部分的正确代码覆盖。

我遇到的问题是如何使用相同的FakeManager类创建测试,该类将抛出异常,以便在无法进行两次唯一调用时执行catch块逻辑并满足代码覆盖率到GetRequest()方法,因为它不采用可用于区分两个不同调用的输入参数?

2 个答案:

答案 0 :(得分:1)

使用返回true的相同ManagerFake类。创建一个引发错误的不同IManager实现。

或者,使用模拟对象库,该库将创建具有您在每次测试中所需行为的模拟对象实例。

答案 1 :(得分:1)

您可能希望研究模拟框架(如Moq:https://github.com/Moq/moq4)。

不是编写模仿所有行为的ManagerFake类,而是模仿行为:

var mock = new Mock<IManager>();
mock.Setup(manager => manager.GetRequest())
    .ReturnsAsync(true);

var mock = new Mock<IManager>();
mock.Setup(manager => manager.GetRequest())
    .Throws(new HTTPResponseException( ... ));