技术开发 频道

基于MVC框架开发Web论坛之测试篇

列表1–Controllers\ForumControllerTest.cs
 

using System.Collections.Generic;
using System.Web.Mvc;
using LinqToSqlExtensions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MvcFakes;
using MvcForums.Controllers;
using MvcForums.Models;

namespace MvcForums.Tests.Controllers
{
    [TestClass]
    
public class ForumControllerTest
    {

        
private IDataContext _dataContext;
        
private IForumRepository _repository;
        
        [TestInitialize]
        
public void Initialize()
        {
            
//创建数据上下文和虚构的数据
            _dataContext = new FakeDataContext();
            _dataContext.Insert(
new Message(1, null, "Robert", "Welcome to the MVC forums!", "body1"));
            _dataContext.Insert(
new Message(2, 1, "Stephen", "RE:Welcome to the MVC forums!", "body2"));
            _dataContext.Insert(
new Message(3, 2, "Robert", "RE:Welcome to the MVC forums!", "body3"));
            _dataContext.Insert(
new Message(4, null, "Mark", "Another message", "body4"));
            _dataContext.Insert(
new Message(5, 4, "Stephen", "Yet another message", "body5"));
            _dataContext.Insert(
new Message(6, 5, "Jane", "Yet another message", "body6"));

            
//创建仓库
            _repository = new ForumRepository(_dataContext);
        }

        [TestMethod]
        
public void IndexReturnsMessageThreads()
        {
            
// Arrange
            var controller = new ForumController(_repository);
            
            
// Act
            var result = controller.Index() as ViewResult;
            
            
// Assert
            var model = result.ViewData.Model as List<Message>;
            Assert.AreEqual(
2, model.Count);
        }
    }
}

 

  列表1中的单元测试类包含了两个方法,名字分别为Initialize()和IndexReturnsMessageThreads()。注意,Initialize()方法前面修饰有[TestInitialize]属性。这个属性能够确保在每一个单元测试之前运行Initialize()方法。

  Initialize()方法用于创建一个模拟的DataContext。一些模拟的论坛消息将被添加到该模拟的DataContext中。注意,一个论坛消息拥有下列属性:
? Id
? ParentId
? Author
? Subject
? Body

  注意,我们现在创建的是一个基于线程的讨论某些主题的论坛程序。其中的论坛消息都是以线程的方式加以组织的。因此,在一个线程中可能存在若干条消息。

  上面的ParentId属性描述了当前消息的父级消息。如果一条消息拥有一个NULL类型的父级消息时,那么,此消息将被假定为是这个线程中的第一条消息。

  因为模拟的DataContext是在Intialize()方法中建立的,所以,测试类中所有的单元测试都可以利用这个模拟的DataContext。
注意,FakeDataContext类是作为MvcFakes工程的一部分存在的,详情请参考本文所附源码。

  上述虚构的DataContext将被传递到Repository类的一个实例中。MVC论坛应用程序将利用Repository模式,其目的是为了解除系统对于任何特定的数据访问技术的依赖性。

  接下来请注意,IndexReturnsMessageThreads()方法负责校验Forums控制器中的Index()方法确保其返回一个消息线程的列表。这个单元测试被分成三个部分。

  在Arrange部分中,将创建一个Forum控制器的实例。注意,当创建控制器时,该repository将被传递到Forum控制器的构造器。在这个单元测试中,Forum控制器将使用借助于虚拟的DataContext实例化的repository。

  接下来,在Act部分中,Index()动作被调用。该Index()动作返回一个ViewResult。

  最后,在Assert部分中,ViewData.Model属性被强制转换成一个消息对象的集合。如果Index()方法返回所有的线程,那么该Index()方法应该正好返回三个消息。记住,一个线程就是一个ParentId为NULL的消息。

  当你第一次试图运行列表1中的单元测试时,该测试将会失败。事实上,你的应用程序甚至不会通过编译—你将得到如图3所示的错误列表窗口。
 

1
相关文章