2013-07-24 10 views
6

Pracuję więc z Umbraco 6.12 i mając wielką trudność mogłem przetestować RenderMvcController.Jednostka Testowanie RenderMvcController jest możliwe?

Zaimplementowałem IApplicationEventHandler w moim Global.ascx, a Ninject działa poprawnie i zgodnie z oczekiwaniami podczas uruchamiania aplikacji - wszystko dobrze.

Jednak testowanie jednostkowe tych kontrolerów to inna sprawa. Znalazłem to, i dodałem ostatnią odpowiedź:

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

Mam teraz ten piękny siekać w moim Setup:

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

Który ma wokół oryginalnego UmbracoContext nie może być null, ale jest teraz rzuca:

Prąd nie został zainicjalizowany na Umbraco.Web.PublishedCache.PublishedCachesResolver. Musisz zainicjować Current, zanim spróbujesz go odczytać.

Opublikowana buforuje rezolwer również wydaje się być ukryty za wewnętrzną i chronionych rzeczy, których nie mogę użyć refleksji włamać na co nie mogę nic na wprost pod SetProperty refleksji init.

To naprawdę frustrujące, kocham v6, a używanie uMapper jest bardzo miłe. Mogę wprowadzić do kontrolerów repozytorium, usługę, polecenie lub zapytanie, a życie jest dobre - po prostu nie mogę objąć kontrolerów!

Każda pomoc w tym zakresie byłaby bardzo doceniana.

Dzięki.

Odpowiedz

10

Do testów jednostkowych Umbraco RenderMvcController, trzeba grab the source code from github, kompilacji roztworowi siebie i uzyskać Umbraco.Tests.dll i odniesienie go w projekcie badawczym.

Oprócz tego należy odwołać się do SQLCE4Umbraco.dll, który jest dystrybuowany z pakietami Umbraco, oraz Rhino.Mocks.dll, który jest wewnętrznie przeznaczony do kpienia.

Aby ci w tym pomóc, skompilowałem plik Umbraco.Tests.dll dla Umbraco 6.1.5 i umieściłem go razem z Rhino.Mocks.dll i umieściłem na this zip file.

Wreszcie wywodzą swój test z BaseRoutingTest, nadpisać DatabaseTestBehavior do NoDatabasePerFixture i uzyskać UmbracoContext i HttpBaseContext przez wywołanie metody GetRoutingContext, jak w poniższym kodzie:

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; 
     } 
    } 
} 

Kod ten został tylko przetestowane w Umbraco 6.1.5.

+0

Dzięki, skończyłem z podobnym. Jest to jednak duży wysiłek - miejmy nadzieję, że w przyszłości dostanie nieco więcej TLC od głównego zespołu. – Jammin

+0

@JorgeLusar, próbuję skonfigurować witrynę umbraco z TDD, wykonując twój przykład, ale mój pierwszy test zawsze kończy się niepowodzeniem. Czy możesz sprawdzić moje pytanie i zobaczyć, czy masz ten sam problem? http://stackoverflow.com/questions/22660255/umbraco-unit-tests-failing Dzięki! –

0

Podniosłem to na forach Umbraco i istnieje kilka odpowiedzi, które mogą ci pomóc.

Zobacz tutaj:

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

Zasadniczo można .. po prostu ... ale wymaga pewnej refleksji, ponieważ niektóre z podstawowych klas i interfejsów są wewnętrzne. Jak wskazuje ostatni post Luke'a, dzieje się tak dlatego, że funkcjonalność jest obecnie nieco ruchomym celem.

Powiązane problemy