要对 Umbraco RenderMvcController 进行单元测试,您需要从 github 获取源代码,自己编译解决方案,并获取 Umbraco.Tests.dll 并在您的测试项目中引用它。
除此之外,您还需要引用随 Umbraco 包分发的 SQLCE4Umbraco.dll,以及内部用于模拟的 Rhino.Mocks.dll。
为了帮助您解决这个问题,我编译了 Umbraco 6.1.5 的 Umbraco.Tests.dll 并将其与 Rhino.Mocks.dll 放在一起并放在这个 zip 文件中。
最后,从 BaseRoutingTest 派生您的测试,将 DatabaseTestBehavior 覆盖为 NoDatabasePerFixture,并通过调用 GetRoutingContext 方法获取 UmbracoContext 和 HttpBaseContext,如下面的代码所示:
using System;
using Moq;
using NUnit.Framework;
using System.Globalization;
using System.Web.Mvc;
using System.Web.Routing;
using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
namespace UnitTests.Controllers
{
public class Entry
{
public int Id { get; set; }
public string Url { get; set; }
public string Title { get; set; }
public string Summary { get; set; }
public string Content { get; set; }
public string Author { get; set; }
public string[] Tags { get; set; }
public DateTime Date { get; set; }
}
public interface IBlogService
{
Entry GetBlogEntry(int id);
}
public class BlogEntryController : RenderMvcController
{
private readonly IBlogService _blogService;
public BlogEntryController(IBlogService blogService, UmbracoContext ctx)
: base(ctx)
{
_blogService = blogService;
}
public BlogEntryController(IBlogService blogService)
: this(blogService, UmbracoContext.Current)
{
}
public override ActionResult Index(RenderModel model)
{
var entry = _blogService.GetBlogEntry(model.Content.Id);
// Test will fail if we return CurrentTemplate(model) as is expecting
// the action from ControllerContext.RouteData.Values["action"]
return View("BlogEntry", entry);
}
}
[TestFixture]
public class RenderMvcControllerTests : BaseRoutingTest
{
protected override DatabaseBehavior DatabaseTestBehavior
{
get { return DatabaseBehavior.NoDatabasePerFixture; }
}
[Test]
public void CanGetIndex()
{
const int id = 1234;
var content = new Mock<IPublishedContent>();
content.Setup(c => c.Id).Returns(id);
var model = new RenderModel(content.Object, CultureInfo.InvariantCulture);
var blogService = new Mock<IBlogService>();
var entry = new Entry { Id = id };
blogService.Setup(s => s.GetBlogEntry(id)).Returns(entry);
var controller = GetBlogEntryController(blogService.Object);
var result = (ViewResult)controller.Index(model);
blogService.Verify(s => s.GetBlogEntry(id), Times.Once());
Assert.IsNotNull(result);
Assert.IsAssignableFrom<Entry>(result.Model);
}
private BlogEntryController GetBlogEntryController(IBlogService blogService)
{
var routingContext = GetRoutingContext("/test");
var umbracoContext = routingContext.UmbracoContext;
var contextBase = umbracoContext.HttpContext;
var controller = new BlogEntryController(blogService, umbracoContext);
controller.ControllerContext = new ControllerContext(contextBase, new RouteData(), controller);
controller.Url = new UrlHelper(new RequestContext(contextBase, new RouteData()), new RouteCollection());
return controller;
}
}
}
此代码仅在 Umbraco 6.1.5 中测试过。