それは強く次の行上のリポジトリに結合されているので、お使いのコントローラが孤立してテストしたユニットであることは不可能である。
NewsRepository n_rep = new NewsRepository();
あなたは単に、リポジトリの特定の実装をハードコーディングし、あなたのユニットテストあなたの中にいますそれを嘲笑することはできません。これを行うために、適切にあなたがこのリポジトリ上の抽象化を定義することによって開始する必要があります:
public interface INewsRepository
{
IEnumerable<NewsItem> GetNews();
}
してから特定のリポジトリは、このインタフェースを実装する必要があり:
public class NewsRepository : INewsRepository
{
...
}
[OK]を、今、我々はのは弱め抽象化を聞かせていることこの抽象化を使用して、データアクセスおよびコントローラロジック間の結合:
public class NewsController: Controller
{
private readonly INewsRepository repository;
public NewsController(INewsRepository repository)
{
this.repository = repository;
}
public ActionResult Index()
{
ViewBag.Message = "Announcements";
var model = this.repository.GetNews();
return View(model);
}
}
さてさて、今あなたがしっかりしなくなっているコントローラを持っていますいくつかの特定の実装と相まって、あなたはお気に入りのモックフレームワークをピックアップし、単体テストを書くことができます。
[TestMethod]
public void Index_Action_Fetches_Model_From_Repo()
{
// arrange
var repo = Substitute.For<INewsRepository>();
IEnumerable<NewsItem> expectedNews = new[] { new NewsItem() };
repo.GetNews().Returns(expectedNews);
var sut = new NewsController(repo);
// act
var actual = sut.Index();
// assert
Assert.IsInstanceOfType(actual, typeof(ViewResult));
var viewResult = actual as ViewResult;
Assert.AreEqual(expectedNews, viewResult.Model);
}
そして、それはかなりそれだ:NSubstitute
と例えばここにindexアクションのためのユニットテストは、次のようになります方法です。あなたのコントローラは単体で簡単にユニットテスト可能です。あなたはデータベースなどを設定する必要はありません。コントローラーのロジックをテストするのはそれがポイントではありません。
これは、私が探している解決策ではない理由がわかりませんが、私はこれらのエラーを受け取ります:1. Public NewsController(INewsRepository repository)でエラー:不整合アクセシビリティ:パラメータタイプ 'TestProject.Models.INewsRepository'は、メソッド 'TestProject.Controllers.NewsController.NewsController(TestProject.Models.INewsRepository)'よりアクセスしにくいです。 ---- 2.行内:var repo = Substitute.For < INewsRepository>();エラー:名前 'Substitute'は現在のコンテキストに存在しません。 ----いくつかの名前空間がありますか? – Mappan
代理人、リンクを確認するのを忘れました。しかし、最初のエラーが起きます。 – Mappan
私の答えに示されているように、すべてのクラスとインタフェースは 'public'である必要があります。 NSubstituteに関するあなたのエラーに関する限り、NSubstitute NuGetをユニットテストプロジェクトにインストールする必要があります。 –