2013-07-24 61 views
6

所以我正在使用Umbraco 6.12,並且很難測試RenderMvcController單元甚至有可能測試RenderMvcController?

我在我的Global.ascx中實現了IApplicationEventHandler,Ninject運行正常,並且按預期運行該應用程序 - 都很好。

但是,單元測試這些控制器是另一回事。我發現這一點,並增加了最新回覆:

http://issues.umbraco.org/issue/U4-1717

我現在在我的設置這個可愛的黑客:

Umbraco.Web.UmbracoContext.EnsureContext(new HttpContextWrapper(new HttpContext(new HttpRequest("", "http://www.myserver.com", ""), new HttpResponse(null))), ApplicationContext.Current); 

裏面有原UmbracoContext周圍有不能爲空,但現在拋出:

目前尚未在Umbraco.Web.PublishedCache.PublishedCachesResolver初始化。在嘗試讀取之前,您必須初始化Current。

公佈的緩存解析器也似乎後面的內部和保護的東西要隱藏,我不能使用反射在我不能初始化任何東西進入SetProperty反射破解。

這真的令人沮喪,我愛v6,並使用uMapper是非常好的。我可以隨時向控制器注入回購,服務,命令或查詢,並且生活是美好的 - 我無法覆蓋控制器!

任何幫助,將不勝感激。

謝謝。

回答

10

單元測試一一把umbraco RenderMvcController,你需要grab the source code from github,自己編譯的解決方案,並獲得Umbraco.Tests.dll,並引用它在你的測試項目。

除此之外,您需要引用與Umbraco包一起分發的SQLCE4Umbraco.dll和內部用於嘲笑的Rhino.Mocks.dll。

爲了解決這個問題,我編譯了Umbraco.Tests.dll,並將其與Rhino.Mocks.dll放在一起,並將其放在this zip file上。

最後,得出從BaseRoutingTest測試,覆蓋DatabaseTestBehavior到 NoDatabasePerFixture,並獲得UmbracoContext和HttpBaseContext通過調用GetRoutingContext方法,如下面的代碼:

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中。

+0

謝謝,我結束了類似的。儘管這是一個很大的努力 - 希望未來能夠從核心團隊中獲得更多的TLC。 – Jammin

+0

@JorgeLusar,我試圖通過以下示例設置帶有TDD的umbraco網站,但我的第一個測試總是失敗。你能檢查我的問題,看看你是否有同樣的問題? http://stackoverflow.com/questions/22660255/umbraco-unit-tests-failing謝謝! –