【问题标题】:ASP.NET MVC 2: What to test in views and controllersASP.NET MVC 2:在视图和控制器中测试什么
【发布时间】:2010-12-05 17:56:18
【问题描述】:

我将 MVC 2 与 MVC contrib 和 Rhino 模拟一起使用。

我需要帮助。这是一个痛苦的周末。我一直在寻找关于如何使用 MVC contrib 对控制器进行测试的好文章。没有人对我有任何体面的答案。我想知道我需要在视图和控制器中测试什么?这是单元测试还是集成测试?

让我描述一下我的基本场景:我有一个索引视图,上面有一个网格。在这个网格中,我有一个新闻项目列表。在这个网格中,每一行的最后一列都有一个 Edit 链接,它将用户带到 EditNews 视图以编辑选定的新闻项目。此索引视图上还有一个添加新闻按钮,可将用户带到 CreateNews 视图。

现在考虑到当前情况,我需要编写哪些测试?你们能否也指出它们是单元测试还是集成测试。我需要为编辑链接编写测试吗?我需要为“添加新闻”按钮编写测试吗?我是否需要编写测试来检查此索引页面是否允许用户访问?这是我目前拥有的:

[Test]
public void Index_Should_Redirect_To_Error_View_When_User_Does_Not_Have_Permission()
{
}

[Test]
public void Index_Should_Log_Exception_When_User_Does_Not_Have_Permission()
{
}

[Test]
public void Index_Should_Return_Default_View()
{
   // Act
   var result = newsController.Index();

   // Assert
   result
      .AssertViewRendered()
      .ForView("Index");
}

更新: 这是我的索引操作方法:

public ActionResult Index()
{
   IEnumerable<News> news = newsRepository.FindAll();
   return View(news);
}

任何体面的文章或示例代码将不胜感激。同样在 MVC contrib 上,代码示例也没多大用处。我想听到尽可能多的意见。

谢谢。

【问题讨论】:

    标签: asp.net-mvc unit-testing integration-testing mvccontrib-testhelper


    【解决方案1】:

    您需要区分单元测试、集成测试和 Web 测试。单元测试用于单独测试代码的不同组件,例如控制器操作。集成测试用于测试代码与外部组件之间的集成,例如从数据库读取和写入数据的存储库,而 Web 测试用于测试应用程序的整个用户场景,例如用户在地址栏中键入一些地址在他的浏览器中,点击某个按钮,...

    MVCContrib.TestHelper 和 Rhino Mocks 旨在简化您的单元测试。因此,在您的场景中,您应该测试您的 Index 控制器操作。如果不显示此控制器操作包含的代码,就很难说出您需要测试什么。一般来说,您可以在控制器操作中进行单元测试的是它验证输入,调用存储库上的正确方法并根据结果返回正确的视图。

    假设您有以下您愿意测试的 Index 操作:

    public class HomeController: Controller
    {
        private readony INewRepository _repository;
        public HomeController(INewRepository repository)
        {
            _repository = repository;
        }
    
        public ActionResult Index()
        {
            var news = _repository.GetNews();
            return View(news);
        }
    }
    

    以及对应的单元测试:

    [TestClass]
    public class HomeControllerTests : TestControllerBuilder
    {
        private HomeController _sut;
        private INewsRepository _repositoryStub;
    
        [TestInitialize()]
        public void MyTestInitialize() 
        {
            _repositoryStub = MockRepository.GenerateStub<INewsRepository>();
            _sut = new UsersController(_repositoryStub);
            InitializeController(_sut);
        }
    
        [TestMethod]
        public void UsersController_Index_Should_Fetch_News_From_Repository()
        {
            // arrange
            var news = new News[0];
            _repositoryStub.Stub(x => x.GetNews()).Return(news);
    
            // act
            var actual = _sut.Index();
    
            // assert
            actual
                .AssertViewRendered()
                .WithViewData<News[]>()
                .ShouldBe(news);
        }
    }
    

    就您的观点而言,您需要编写 Web 测试来验证它们的行为是否符合预期。这里有不同的工具可以帮助您,例如 Selenium 或直接使用 Web Tests 如果您拥有 Visual Studio 的 Ultimate 版本。 Steven Sanderson 还 proposed an interesting approach 测试您可能会查看的视图。

    【讨论】:

    • 查看更新后的帖子。我仍然不明白这一点。我上面提到的测试,到目前为止还行吗?你还有什么单元测试和集成测试?如果您能提供一些样品,我将不胜感激。
    • @Brendan,您的控制器的 Index 操作应该进行单元测试。请参阅我的代码示例。它看起来和我给你看的很相似。
    • 谢谢。只是另一个新手问题,您在 1 次测试中没有做太多事情吗?您检查是否呈现了正确的视图,并且您正在调用存储库?这些不应该是两个单独的测试吗?另外,您何时确认调用了 GetNews?在同一个测试中?还是分开?
    • 因为在这个测试中控制器动作非常简单,所以我正在验证 GetNews 方法的结果是否已传递给视图。所以我要验证两件事:调用 GetNews 操作并呈现视图。因为这就是这个动作所做的一切,所以这就足够了。由于我们已经在一次测试中涵盖了所有内容,因此无需对此操作进行更多测试。对于更复杂的操作,您可能需要拆分测试。例如,如果您有条件,则需要单独测试。
    猜你喜欢
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    相关资源
    最近更新 更多