NuGetGalleryでユニットテストが行われる方法を見てきました。コントローラをテストすると、サービスクラスがモックされていることがわかりました。これは私にとって理にかなっています。なぜなら、コントローラーロジックをテストしている間、下のアーキテクチャーレイヤーについて心配したくなかったからです。このアプローチをしばらく使用した後、サービスクラスが変更されたときに、コントローラーテスト全体でモックの修正を頻繁に実行していることに気付きました。この問題を解決するために、私より賢い人に相談することなく、私はこのようなテストを書き始めました(心配しないでください、私はそれほど遠くまで来ていません):
public class PersonController : Controller
{
private readonly LESRepository _repository;
public PersonController(LESRepository repository)
{
_repository = repository;
}
public ActionResult Index(int id)
{
var model = _repository.GetAll<Person>()
.FirstOrDefault(x => x.Id == id);
var viewModel = new VMPerson(model);
return View(viewModel);
}
}
public class PersonControllerTests
{
public void can_get_person()
{
var person = _helper.CreatePerson(username: "John");
var controller = new PersonController(_repository);
controller.FakeOutContext();
var result = (ViewResult)controller.Index(person.Id);
var model = (VMPerson)result.Model;
Assert.IsTrue(model.Person.Username == "John");
}
}
私は実際のデータベースを使用しているので、これは統合テストになると思います(インメモリデータベースが望ましいです)。データベースにデータを配置することからテストを開始します(各テストはトランザクションで実行され、テストが完了するとロールバックされます)。次に、コントローラーを呼び出します。ビューに送信されるモデルに、データベースに入れたレコード(アサーション)が必要なだけで、データベースから(リポジトリまたはサービスクラスを介して)データを取得する方法はまったく気にしません。 。このアプローチの優れた点は、コントローラーのテストを変更せずに、多くの場合、複雑さのレイヤーを追加し続けることができることです。
public class PersonController : Controller
{
private readonly LESRepository _repository;
private readonly PersonService _personService;
public PersonController(LESRepository repository)
{
_repository = repository;
_personService = new PersonService(_repository);
}
public ActionResult Index(int id)
{
var model = _personService.GetActivePerson(id);
if(model == null)
return PersonNotFoundResult();
var viewModel = new VMPerson(model);
return View(viewModel);
}
}
これで、PersonServiceのインターフェイスを作成して、コントローラーのコンストラクターに渡していないことに気付きました。その理由は、1)PersonServiceをモックする予定がないこと、および2)PersonControllerが1つのタイプのPersonServiceにのみ依存する必要があるため、依存関係を注入する必要がないと感じたことです。
私はユニットテストに不慣れで、自分が間違っていることが示されることを常に嬉しく思っています。コントローラーをテストする方法が本当に悪い考えである理由を指摘してください(テストの実行にかかる時間が明らかに増加することを除けば)。