技术开发 频道

基于MVC框架开发Web论坛之新功能篇

  二、 创建新的单元测试

  因为我正在遵循测试驱动开发思想构建本文中的论坛应用程序,所以我总是先从创建一组新的单元测试开始。列表1显示了这一组新的单元测试。

  列表1—Controllers\ForumControllerTest.cs

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

namespace MvcForums.Tests.Controllers
{

    [TestClass]
    
public class ForumControllerTest
    {
        
private IForumRepository _repository;
      
        [TestInitialize]
        
public void Initialize()
        {
            
//创建模拟数据
            var dataContext
= new FakeDataContext();
            dataContext.Insert(
new Message(1, null, null, "Robert", "Welcome to the MVC forums!", "body1"));
            dataContext.Insert(
new Message(2, 1, 1, "Stephen", "RE:Welcome to the MVC forums!", "body2"));
            dataContext.Insert(
new Message(3, 1, 2, "Robert", "RE:Welcome to the MVC forums!", "body3"));
            dataContext.Insert(
new Message(4, null, null, "Mark", "Another message", "body4"));
            dataContext.Insert(
new Message(5, 4, 4, "Stephen", "Yet another message", "body5"));
            dataContext.Insert(
new Message(6, 4, 5, "Jane", "Yet another message", "body6"));
            
            
//返回repository
            _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);
        }

        
/// <summary>
        
///验证Thread(1)动作将返回3条消息,而且所有的消息都有一个
        
///值为1的Id或者ParentThreadId属性
        
/// </summary>
        [TestMethod]
        
public void ThreadReturnsMessagesInThread()
        {
            
// Arrange
            var controller
= new ForumController(_repository);

            
// Act
            var result
= controller.Thread(1) as ViewResult;

            
// Assert
            var model
= result.ViewData.Model as List<Message>;
            Assert.AreEqual(
3, model.Count); //第一个线程中的3条消息
            foreach (var m in model)
            {
                Assert.IsTrue(m.Id
== 1 || m.ParentThreadId == 1);
            }
        }

        [TestMethod]
        
public void NewThreadIncrementsThreadCount()
        {
            
// Arrange
            var controller
= new ForumController(_repository);
            var originalThreadCount
= _repository.SelectThreads().Count;

            
// Act
            var form
= new FormCollection();
            form.Add(
"author", "Stephen");
            form.Add(
"subject", "New Thread!");
            form.Add(
"body", "Body of new thread");
            var result
= controller.Create(form);

            
// Assert
            var newThreadCount
= _repository.SelectThreads().Count;
            Assert.AreEqual(originalThreadCount
+ 1, newThreadCount);  
        }

        [TestMethod]
        
public void NewReplyIncrementsMessageCount()
        {
            
// Arrange
            var controller
= new ForumController(_repository);
            var originalMessageCount
= _repository.SelectMessages(1).Count;

            
// Act
            var form
= new FormCollection();
            form.Add(
"parentThreadId", "1");
            form.Add(
"parentMessageId", "1");
            form.Add(
"author", "Stephen");
            form.Add(
"subject", "New Thread!");
            form.Add(
"body", "Body of new thread");
            var result
= controller.Create(form);

            
// Assert
            var newMessageCount
= _repository.SelectMessages(1).Count;
            Assert.AreEqual(originalMessageCount
+ 1, newMessageCount);
        }

        [TestMethod]
        
public void NewReplyDoesNotIncrementsThreadCount()
        {
            
// Arrange
            var controller
= new ForumController(_repository);
            var originalThreadCount
= _repository.SelectThreads().Count;

            
// Act
            var form
= new FormCollection();
            form.Add(
"parentThreadId", "1");
            form.Add(
"parentMessageId", "1");
            form.Add(
"author", "Stephen");
            form.Add(
"subject", "New Thread!");
            form.Add(
"body", "Body of new thread");
            var result
= controller.Create(form);

            
// Assert
            var newThreadCount
= _repository.SelectThreads().Count;
            Assert.AreEqual(originalThreadCount, newThreadCount);
        }

    }
}

 列表1中的测试类包含下列单元测试:
? IndexReturnsMessageThreads()—验证Index()动作将返回2条ParentThreadId属性为NULL的消息;
? ThreadReturnsMessagesInThread()—验证Thread()动作将返回一个指定线程中的所有消息;
? NewThreadIncrementsThreadCount()—验证发送一条新的没有提供ParentThreadId属性的消息将使消息线程数加1;
? NewReplyIncrementsMessageCount()—验证把一条应答消息发送到一个线程将使该线程中的消息数加1;
? NewReplyDoesNotIncrementThreadCount()—验证发送一条应答消息不会增加总线程的数目。
  上面这些单元测试应该是非常易于理解的。它们都利用了虚构的DataContext类。通过这种方式,数据库本身是不会被实际上使用或修改的。

  此外还请注意,这些单元测试本身并不会与DataContext类直接交互。而是,这些单元测试仅仅与ForumRepository类交互。通过这种方式,如果我们决定改变我们的数据访问技术—例如,我们把LINQ to SQL改变为NHibernate—那么,我们不需要改变我们的单元测试。如果我们改变数据访问技术,那么,我们仅仅需要改变Initialize()方法。
 

 

0
相关文章