测试控制器与asp.net mvc中的单元工作

时间:2012-11-12 21:25:16

标签: asp.net-mvc unit-testing moq

我有一个模特:

public class Post: 
    {
        public string Description { get; set; }
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        public string Name { get; set; }

        public Guid UniqId { get; set; }

        public DateTime CreatedDate { get; set; }

        public byte[] RowVersion { get; set; }

    }

我有一个具有EfContext和Iunitofwok模式的DataLayer

using System.Data.Entity;

    namespace Data
    {
        public interface IUnitOfWork
        {
            IDbSet<TEntity> Set<TEntity>() where TEntity : class;
            int SaveChanges();
        }
    }

using System.Data.Entity;
using DomainModel;





namespace Data
{
    public class EfContext : DbContext, IUnitOfWork
    {
        public DbSet<Post> Post { get; set; }
        public DbSet<Comment> Comments { get; set; }
        public DbSet<Category> Categories { get; set; }
        public EfContext()
            : base("TavanGruop")
        {
        }

        #region IUnitOfWork Members

        public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
        {
            return base.Set<TEntity>();
        }

        #endregion
    }
}

在另一个项目中我有资源库

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using Data;

namespace ServiceLayer.ServiceDbSet
{
    public class ServiceContext<T> : IServiceDbSet<T> where T : class
    {
        private readonly IDbSet<T> _dbSet;

        public  ServiceContext(IUnitOfWork iUnitOfWork)
        {
            _dbSet = iUnitOfWork.Set<T>();
        }

        #region IContext<T> Members

        public bool TryGet(Func<T, bool> predicate, out T entity)
        {
            entity = List(predicate).SingleOrDefault();
            return entity != null;
        }

        public T Get(Func<T, bool> predicate)
        {
            return List(predicate).Single();
        }

        public virtual List<T> List(Func<T, bool> predicate = null)
        {
            IEnumerable<T> result = _dbSet.AsEnumerable();
            if (predicate != null)
                result = result.Where(predicate);
            return result.ToList();
        }

        public T Add(T t)
        {
            _dbSet.Add(t);
            return t;
        }

        public void Delete(Func<T, bool> predicate)
        {
            List(predicate).ToList().ForEach(p => _dbSet.Remove(p));
        }

        public void Delete(T t)
        {
            _dbSet.Remove(t);
        }

        #endregion
    }
}

和服务

using Data;
using DomainModel;
using ServiceLayer.ServiceDbSet;

namespace ServiceLayer.EfServices
{
    public class EfPostService : ServiceContext<Post>
    {
        public EfPostService(IUnitOfWork uow)
            : base(uow)
        {
        }
    }
}

这是我的服务

using Data;
using ServiceLayer.EfServices;

namespace ServiceLayer
{
    public class Services
    {
        private readonly IUnitOfWork _unitOfWork;

        private EfPostService _post;
        private EfCommentService _comment;

        public Services(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public EfPostService Post
        {
            get { return _post ?? new EfPostService(_unitOfWork); }
            set { _post = value; }
        }

        public EfCommentService Comment
        {
            get { return _comment ?? new EfCommentService(_unitOfWork); }
            set { _comment = value; }
        }
    }
}

我使用tructuremap进行依赖注入

using System;
using System.Web.Mvc;
using System.Web.Routing;
using Data;
using StructureMap;

namespace MVCTemplateProject
{
    public static class StructuremapMvc
    {
        public static void InitStructureMap()
        {
            ObjectFactory.Initialize(x => x.For<IUnitOfWork>().HttpContextScoped().Use(() => new EfContext()));
            ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
        }
    }

    public class StructureMapControllerFactory : DefaultControllerFactory
    {
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            return ObjectFactory.GetInstance(controllerType) as Controller;
        }
    }
}

在基础控制器中我获得了Iunitofwork

using System.Web.Mvc;
using Data;
using ServiceLayer;

namespace MVCTemplateProject.Controllers
{
    public class BaseController : Controller
    {
        public readonly IUnitOfWork Context;
        public readonly Services DataContext;

        public BaseController(Data.IUnitOfWork context)
        {
            Context = context;
            DataContext = new Services(context);
        }
    }
}

这是我的家庭控制器

using System.Web.Mvc;
using Data;
using DomainModel;

namespace MVCTemplateProject.Controllers
{
    public class HomeController : BaseController
    {
        public HomeController(IUnitOfWork context)
            : base(context)
        {
        }

        public ActionResult Index()
        {
            return View(DataContext.Post.List());
        }
    }
}

如何使用moq测试索引操作 我写这个测试,但我得到错误

public void IndxShouldReturnListOfPage()
{
    var posts = new List<Post>
                    {
                        new Post {Name = "Test"},
                        new Post {Name = "Test"},
                        new Post {Name = "Test"},
                        new Post {Name = "Test"}
                    };
    var efContext = new Mock<EfContext>();
    var mockRepository = new Mock<ServiceLayer.Services>(efContext);
    mockRepository.Setup(x => x.Post.List(It.IsAny<Func<Post, bool>>())).Returns(posts);

    var controller = new HomeController(efContext.Object);

    List<Post> model = controller.DataContext.Post.List();
    var result = controller.Index() as ViewResult;

    Assert.AreEqual(model.Count, 4);
    Assert.AreEqual(string.Empty, result.ViewName);
}

1 个答案:

答案 0 :(得分:0)

我明白了,我测试了项目

 [TestFixture]
    public class PostControllerTest
    {
        #region Setup/Teardown

        [SetUp]
        public void Setup()
        {
            UnitOfWork = TestHelper.TestHelper.GetMockUnitOfWork();
            PostDbSet = TestHelper.TestHelper.GetMockPostDbSet();
            Posts = TestHelper.TestHelper.GetFakePosts();
            TagDbSet = TestHelper.TestHelper.GetMockTagDbSet();
            CategoryDbSet = TestHelper.TestHelper.GetMockCategoryDbSet();

            PostController = new PostController(UnitOfWork.Object, PostDbSet.Object, CategoryDbSet.Object, TagDbSet.Object);
        }

        #endregion

        private Mock<IServiceDbSet<Post>> PostDbSet { get; set; }
        private Mock<IServiceDbSet<Tag>> TagDbSet { get; set; }
        private Mock<IServiceDbSet<Category>> CategoryDbSet { get; set; }
        private PostController PostController { get; set; }
        private List<Post> Posts { get; set; }

        private Mock<IUnitOfWork> UnitOfWork { get; set; }

        [Test]
        public void DetailShouldRedirectToHomePageWhenNotFoundPostOrPostIdIs0()
        {
            PostDbSet.Setup(x => x.Get(It.IsAny<Func<Post, bool>>())).Returns(Posts.Find(post => post.Id == 100));

            var redirectToRoutResult =
                (RedirectToRouteResult) PostController.Details(100);

            Assert.AreEqual("Index", redirectToRoutResult.RouteValues["action"]);
            Assert.AreEqual("Home", redirectToRoutResult.RouteValues["Controller"]);
        }

        [Test]
        public void DetailShouldShowPostById()
        {
            PostDbSet.Setup(x => x.Get(It.IsAny<Func<Post, bool>>())).Returns(Posts.First());
            var result = PostController.Details(1) as ViewResult;
            var model = result.Model as PostViewModel;

            Assert.AreNotEqual(null, model);
            Assert.AreEqual("I Can", model.Title);
            Assert.AreEqual(string.Empty, result.ViewName);
        }

        [Test]
        public void ListOfStringTagMustConvertToListOfTagCollection()
        {
            PostViewModel postViewModel = TestHelper.TestHelper.GetFakePostViewModel();
            PostController.Create(postViewModel);
            //Assert.AreEqual(postViewModel.RawTags[0], postViewModel.RawTags.First().Name);
        }