2013-07-24 7 views
6

私はUmbraco 6.12で作業しており、大きな困難を抱えてRenderMvcControllerをテストできました。ユニットRenderMvcControllerをテストすることも可能ですか?

私はGlobal.ascxIApplicationEventHandlerを実装しており、Ninjectは正常に動作しており、アプリケーションを実行するときには正常に動作しています。

しかし、これらのコントローラをテストするユニットは、別の問題です。私はこれを見つけ、最新の返信追加しました:

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

が、私は今、私のセットアップでこの素敵なハックがあります:元UmbracoContextの周りに持っている

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

はnullにすることはできませんが、しかし、です現在投げている:

現在はUmbraco.Web.PublishedCache.PublishedCachesResolverで初期化されていません。あなたはそれを読む前にCurrentを初期化する必要があります。

公表キャッシュリゾルバはまた、私は私がSetProperty反射に合格するために何かを初期化することができないようにハックするためにリフレクションを使用することはできませんこれは、内部および保護されたものの背後に隠されているように見えます。

これは本当にイライラしています。私はv6を愛していて、uMapperを使用しているのはとてもいいです。レポ、サービス、コマンド、またはクエリをコントローラに自由に注入することができ、人生は良いです - 私はコントローラをカバーできません!

これに関するお手伝いがあれば幸いです。

ありがとうございました。

答えて

10

は、あなたが解決策を自分でコンパイルし、Umbraco.Tests.dllを取得し、あなたのテストプロジェクトでそれを参照し、grab the source code from githubする必要があります。

さらに、Umbracoパッケージで配布されているSQLCE4Umbraco.dllと、mockingのために内部的に使用されているRhino.Mocks.dllを参照する必要があります。

Umbraco 6.1.5用のUmbraco.Tests.dllをコンパイルして、Rhino.Mocks.dllと一緒に入れてthis zip fileに貼り付けました。

最後に、 NoDatabasePerFixtureにDatabaseTestBehaviorをオーバーライドし、BaseRoutingTestからテストを導出し、以下のコードのように、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。

+0

ありがとう、私は似ていた。それは大きな努力だが、将来的にはコアチームからもう少しTLCが得られることを願っている。 – Jammin

+0

@JorgeLusar、私はあなたの例に従ってTumbとumbracoのウェブサイトを設定しようとしていますが、私の最初のテストは常に失敗します。私の質問をチェックして、同じ問題があるかどうか確認してください。 http://stackoverflow.com/questions/22660255/umbraco-unit-tests-failingありがとう! –

0

私はUmbracoフォーラムでこれを提起しました。あなたに役立ついくつかの回答があります。ちょうど..あなたのことができ、基本的に

http://our.umbraco.org/forum/developers/api-questions/37255-How-can-I-unit-test-a-class-inheriting-from-SurfaceController

...しかし、主要なクラスおよびインタフェースの一部が内部にあるので、いくつかの反射を必要とします。

はこちらを参照してください。ルークの最後の記事が指摘しているように、これは機能が現在は少し動いているためです。

関連する問題