Ошибки модульного тестирования ASP.NET MVC 2 - PullRequest
0 голосов
/ 17 августа 2010

Я работаю над книгой Professional ASP.NET MVC 2 и пытаюсь заставить модульное тестирование в главе 1 работать правильно;однако я получаю некоторые очень странные ошибки.

В решении два проекта: NerdDinner и NerdDinner.Tests.

В проекте NerdDinner у меня есть следующий интерфейс:

IDinnerRepository.cs

//...
namespace NerdDinner.Models
{
     interface IDinnerRepository
     {
     //...
     }
}

Также в проекте NerdDinner у меня есть следующий класс:

//...
using NerdDinner.Models;
//...
namespace NerdDinner.Controllers
{
     public class DinnersController : Controller
     {
     IDinnerRepository dinnerRepository;
     // Default constructor
     public DinnersController() : this(new DinnerRepository()){} // DinnerRepository is another concrete implementation of IDinnerRepository
     //Test constructor
     public DinnersController(IDinnerRepository repository) {
     dinnerRepository = repository;
     }
     }
}

В проекте NerdDinner.Tests у меня есть следующая конкретная реализацияIDinnerRepository:

//...
using NerdDinner.Models;
//...
namespace NerdDinner.Tests.Fakes
{
     class FakeDinnerRepository : IDinnerRepository
     {
     //...
          public FakeDinnerRepository(List<Dinner> dinners)
          {
          //...
          }
     //...
     }
}

Теперь для фактического модульного теста (в NerdDinner.Tests)

using NerdDinner.Controllers;
//...
using NerdDinner.Models;
using NerdDinner.Tests.Fakes;
namespace NerdDinner.Tests
{
     [TestClass]
     public class DinnersControllerTest
     {
          List<Dinner> CreateTestDinners()
          {
          //...
          }
          DinnersController CreateDinnersController()
          {
          return new DinnersController(new FakeDinnerRepository(CreateTestDinners()));
          }
     }
}

А теперь для актуальной проблемы: в методе CreateDinnersController в классе DinnerControllerClass яполучая следующую ошибку:

DinnersController.DinnersController (репозиторий NerdDinner.Models.IDinnerRepository) (+ 1 перегрузка (и)) Ошибка: лучший перегруженный метод соответствует для 'NerdDinner.Controllers.DinnersController.DinnersController.DinnersController.DinnersController.DinnersController.DinnersController.DinnersController.DinnersController.DinnersController.DinnersController.DinnersController.DinnersControllerNerdDinner.Models.IDinnerRepository) 'содержит недопустимые аргументы.

Это дает мне возможность cсоздайте заглушку конструктора в DinnersController.Он генерирует следующий код:

private global::NerdDinner.Tests.Fakes.FakeDinnerRepository repository;
//...
public DinnersController(global::NerdDinner.Tests.Fakes.FakeDinnerRepository repository)
{
     // TODO: Complete member initialization
     this.repository = repository;
}

Даже после генерации этого кода, я все еще получаю ту же ошибку.Но зачем мне вообще нужен этот код?Насколько я могу судить, я все делаю правильно.

Кто-нибудь может мне помочь разобраться, что здесь происходит?

Редактировать Сгенерированный код даетследующая ошибка:

Тип или пространство имен 'Тесты' не существует в пространстве имен 'NerdDinner' (вам не хватает какой-либо ссылки на сборку?)

Ответы [ 2 ]

1 голос
/ 17 августа 2010

Из того, что вы показали, интерфейс IDinnerRepository является , а не публичным, что означает, что он не виден из вашего модульного теста.Я бы порекомендовал вам сделать его общедоступным, так как я подозреваю, что у вас есть два разных интерфейса: один, определенный в модульном тесте, и другой в вашем проекте, который конфликтует.Также я бы порекомендовал вам не полагаться на то, что Visual Studio сгенерирует весь код отражения дерьма, чтобы протестировать частные и внутренние члены.

1 голос
/ 17 августа 2010

Последняя ошибка, которую вы получаете, связана с отсутствием ссылки из рабочего кода на тестовый код - но это уместно.Вам не нужен этот дополнительный конструктор.

Вместо этого вам нужно выяснить, почему не используется существующий конструктор, принимающий IDinnerRepository.Вы уверены, что у вас есть только один интерфейс с именем IDinnerRepository?Если вы перейдете к источнику FakeDinnerRepository, перейдите к объявлению, поместите курсор в IDinnerRepository и нажмете F12 (перейти к определению), он перейдет в нужное место?в IDinnerRepository (просто ради тестирования: void Foo(); было бы хорошо), это приводит к сбою как производственной, так и фиктивной реализации?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...