asp.net-mvc-3 - 您应该如何对 MVC3 中的存储库类进行单元测试?

标签 asp.net-mvc-3 testing

我正在尝试对从存储库类获取数据的 Controller 进行测试。 这是我要测试的存储库的一部分:

public class NewsRepository
{
    public IEnumerable<NewsItem> GetNews()
    {
        var result = (from n in n_db.NewsItems
                     orderby n.ID descending
                     select n).Take(3);
        return result;
    }
}

只需一些小代码即可了解测试的工作原理。 在我的 HomeController 中,我在 Index() 中得到了这段代码:

    public ActionResult Index()
    {
        ViewBag.Message = "Announcements";
        NewsRepository n_rep = new NewsRepository();
        var model = i_rep.GetNews();

        return View(model);
    }

我对测试完全陌生,所以所有的解释都很好。 谢谢。

最佳答案

您的 Controller 不可能单独进行单元测试,因为它在以下行中与您的存储库强耦合:

NewsRepository n_rep = new NewsRepository();

您只是对存储库的特定实现进行了硬编码,并且在您的单元测试中您不能模拟它。为了正确地做到这一点,您应该首先在此存储库上定义一个抽象:

public interface INewsRepository
{
    IEnumerable<NewsItem> GetNews();
}

然后让您的特定存储库实现此接口(interface):

public class NewsRepository : INewsRepository
{
    ...
}

好的,现在我们有了一个抽象,让我们通过使用这个抽象来削弱数据访问和 Controller 逻辑之间的耦合:

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);
    }    
}

好了,现在您有了一个不再与某些特定实现紧密耦合的 Controller 。您可以选择自己喜欢的模拟框架并编写单元测试。例如 NSubstitute Index 操作的单元测试可能如下所示:

[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);
}

差不多就这些了。您的 Controller 现在可以轻松地单独进行单元测试。您不需要设置数据库或其他任何东西。这不是测试 Controller 逻辑的重点。

关于asp.net-mvc-3 - 您应该如何对 MVC3 中的存储库类进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16540720/

相关文章:

ASP.Net MVC 动态 DropDownList - 如何创建一个

c# - 嵌套复杂类型的显示名称

c# - 返回一个列表< Id :int, Name:string>

testing - 在页面模型中将参数传递给 TestCafe Selector

ruby-on-rails - RSpec 未定义的局部变量或方法

testing - gradle beforeSuite {}和afterSuite {}执行多次

asp.net-mvc - 如何在 MVC3 中创建简单的路由?

asp.net-mvc-3 - 如何读取 ASP.Net MVC 3 Web API 2.1 Controller 中的 POST 数据?

testing - gradle build 不生成 jacoco 测试报告

unit-testing - Powermock - 如何模拟一个特定的方法并保持对象的其余部分不变