Как написать модульный тест C# для правильного покрытия кода в блоке try catch

У меня есть следующий код:

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 для модульного тестирования. Для модульных тестов у меня есть класс FakeManager, зарегистрированный в моем контейнере IOC, который содержит метод GetResult() и просто возвращает Task.FromResult(true) при выполнении. Это позволяет выполнить логику в блоке try и, таким образом, обеспечить надлежащее покрытие кода для этого раздела.

Проблема, с которой я сталкиваюсь, заключается в том, как создать тест с использованием того же класса FakeManager, который будет генерировать исключение, чтобы выполнялась логика блока catch и удовлетворялось покрытие кода, когда нет возможности сделать два уникальных вызова GetRequest. (), так как он не принимает входные параметры, которые можно было бы использовать для различения двух разных вызовов?


person Jason    schedule 09.05.2018    source источник
comment
Вы не возвращаете исключение, вы выдаете его, поэтому сделайте так, чтобы ваш фиктивный метод .GetRequest() выдавал исключение.   -  person Lasse V. Karlsen    schedule 09.05.2018


Ответы (2)


Вы не используете тот же класс ManagerFake, который возвращает true. Создайте другую реализацию IManager, которая выдает ошибку.

Или используйте библиотеку фиктивных объектов, которая будет создавать экземпляры фиктивных объектов с именно тем поведением, которое вы хотите в каждом тесте.

person Eric King    schedule 09.05.2018
comment
У меня ограниченный опыт работы с Mock, поэтому мне любопытно, выполняется ли фактический метод конкретного класса или вы просто издеваетесь над поведением указанного метода? Мне нужно получить покрытие кода для рассматриваемого метода. - person Jason; 10.05.2018

Вы, вероятно, захотите изучить фиктивный фреймворк (например, 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( ... ));
person Wireless    schedule 09.05.2018