2016-06-28 2 views
2

Я довольно новичок в использовании Moq и Nunit для модульного тестирования, и у меня возникают проблемы с одним сценарием. Я хочу, чтобы мой макет имел параметры, которые моя тестируемая система будет использовать, чтобы решить, какие действия предпринять.Параметры Moq out

Моя тестируемая система - это контроллер MVC API и, в частности, я пытаюсь протестировать метод POST. Я хочу вернуть сообщение об ошибке для объекта, когда проверка не удалась.

Вот метод код для контроллера:

 public IHttpActionResult Post(Candidate candidate) 
    { 
     try 
     { 
      if(candidate==null) 
       return BadRequest(); 

      IEnumerable<string> errors; 
      _candidateManager.InsertCandidate(candidate, out errors); 

      if (errors!=null && errors.Any()) 
       return BadRequest(CreateErrorMessage("Invalid candidate: ", errors)); 

      return CreatedAtRoute("DefaultApi", new {id = candidate.CandidateId}, candidate); 

     } 
     catch (Exception) 
     { 
      return InternalServerError(); 
     } 
    } 

Это мой блок Код проверки:

 [Test] 
    [Category("CandidateManagerController Unit Tests")] 
    public void Should_Return_Bad_Request_When_Creating_Invalid_Candidate() 
    { 
     IEnumerable<string> errors = new List<string>() {"error1", "error2"}; 

     var mockManager = new Mock<ICandidateManager>(); 
     mockManager.Setup(x => x.InsertCandidate(new Candidate(), out errors)).Callback(()=>GetErrors(errors)); 

     var sut = new CandidateManagerController(mockManager.Object); 

     var actionResult = sut.Post(new Candidate()); 

     Assert.IsInstanceOf<BadRequestResult>(actionResult); 

    } 

Что я ожидаю, что когда _candidateManager.InsertCandidate() выполняется тогда ошибки переменная заполняется. Однако то, что происходит, заключается в том, что при выполнении кода кода контроллера ошибки равны нулю после запуска метода _candidateManager.InsertCandidate().

Если у кого-то есть идеи, что я делаю неправильно, или если то, что я хочу сделать, невозможно с помощью Moq, то, пожалуйста, дайте мне знать.

Благодаря

+0

Вы должны установить ошибки. Какова реализация GetErrors? –

ответ

0

Вы должны убедиться, что при вызове SUT, что вы используете один и тот же экземпляр передается в out аргумент в противном случае вызов не удастся.

В вашем примере тестируемый метод передает нулевой экземпляр в издевательский метод, тем самым отрицая настройку теста.

Если, однако, вы не можете предоставить одинаковые экземпляры для out, тогда это не похоже, что вы сможете получить макет, чтобы пройти успешно. Взгляните на Quick Start for Moq, чтобы получить представление об этом.

+0

Привет, спасибо за ответы до сих пор. Извинения, код, который устанавливает макет, должен быть «var mockManager = new Mock (); mockManager.Setup (x => x.InsertCandidate (new Candidate(), out errors)); 'Когда я помещаю точку прерывания в строку actionResult, я вижу, что ошибки содержат два элемента, которые я ожидаю, но когда вы входите в код контроллера ошибки IEnumerable не устанавливается при вызове метода. Чтение быстрого запуска MOQ похоже, что я настроил его так же. Я не уверен, действительно ли то, что я хочу сделать, на самом деле возможно. – kcis8rm

1

Что вы хотите сделать, это возможно. Если вы посмотрите на документы Quickstart по адресу https://github.com/Moq/moq4/wiki/Quickstart, есть раздел, где показано, как вы настраиваете методы, используя параметры. Я сделал две поправки к вашему коду, и он работает.

  1. Вы должны использовать один и тот же экземпляр экземпляра как для установки макета, так и при выполнении сут. В противном случае Мок думает, что эти два объекта различны, и ваша тестовая установка становится бесполезной.
  2. Вам не нужно использовать обратный вызов, чтобы установить ошибки, вызванные запутанным CandidateManager. Ниже приведен ваш метод тестирования с моими изменениями.

    [Test] 
    [Category("CandidateManagerController Unit Tests")] 
    public void Should_Return_Bad_Request_When_Creating_Invalid_Candidate() 
    { 
    IEnumerable<string> errors = new List<string>() {"error1", "error2"}; 
    
    //instance to be used for both setup and test later 
    var candidate = new Candidate(); 
    
    var mockManager = new Mock<ICandidateManager>(); 
    
    //removed Callback 
    mockManager.Setup(x => x.InsertCandidate(candidate, out errors)); 
    
    var sut = new CandidateManagerController(mockManager.Object); 
    
    var actionResult = sut.Post(candidate); 
    
    Assert.IsInstanceOf<BadRequestResult>(actionResult); 
    
    } 
    
Смежные вопросы