Frage Unit Testen eines RenderMvcControllers sogar möglich?


Also arbeite ich mit Umbraco 6.12 und habe große Schwierigkeiten, einen Test zu machen RenderMvcController.

Ich habe es implementiert IApplicationEventHandler in meinem Global.ascx und Ninject funktioniert gut und wie erwartet beim Ausführen der Anwendung - alles gut.

Das Testen dieser Controller ist jedoch eine andere Sache. Ich habe das gefunden und die letzte Antwort hinzugefügt:

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

Ich habe jetzt diesen schönen Hack in meinem SetUp:

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

Was hat das Original bekommen UmbracoContext kann nicht null sein, wirft aber jetzt:

Current wurde nicht auf Umbraco.Web.PublishedCache.PublishedCachesResolver initialisiert. Sie müssen Current initialisieren, bevor Sie versuchen, es zu lesen.

Der veröffentlichte Caches-Resolver scheint auch hinter internen und geschützten Dingen versteckt zu sein, auf die ich keine Reflexion anwenden kann, da ich nichts initiieren kann, um daran zu gelangen SetProperty Betrachtung.

Es ist wirklich frustrierend, ich liebe v6 und die Verwendung von uMapper ist sehr nett. Ich kann nach Belieben ein Repo, einen Service, einen Befehl oder eine Abfrage in die Controller einfügen und das Leben ist gut - ich kann die Controller einfach nicht abdecken!

Jede Hilfe dazu wäre sehr willkommen.

Vielen Dank.


6
2017-07-24 11:02


Ursprung


Antworten:


Um einen Umbraco RenderMvcController Unit-Test zu testen, müssen Sie Nimm den Quellcode von Github, kompilieren Sie die Lösung selbst und holen Sie die Umbraco.Tests.dll und verweisen Sie sie auf Ihr Testprojekt.

Darüber hinaus müssen Sie auf die SQLCE4Umbraco.dll verweisen, die mit den Umbraco-Paketen verteilt wird, und auf Rhino.Mocks.dll, die intern für Spott ist.

Um Ihnen dabei zu helfen, habe ich die Umbraco.Tests.dll für Umbraco 6.1.5 zusammengestellt und zusammen mit der Rhino.Mocks.dll erstellt und angelegt diese Zip-Datei.

Abschließend leiten Sie Ihren Test von BaseRoutingTest ab, überschreiben Sie das DatabaseTestBehavior zu NoDatabasePerFixture, und rufen Sie UmbracoContext und HttpBaseContext ab, indem Sie die GetRoutingContext-Methode wie im folgenden Code aufrufen:

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

Dieser Code wurde nur in Umbraco 6.1.5 getestet.


10
2017-09-18 10:01



Entsprechend dem Kernteam sollten Sie die Umbraco.Tests-Bibliothek einschließen und Ihren Test von BaseUmbracoApplicationTest erben. Das wird eine gültige UmbracoApplication und UmbracoContext einrichten.

https://groups.google.com/forum/?fromgroups=#!topic/umbraco-dev/vEjdzjqmtsU


1
2017-08-29 21:53



Ich habe dies in den Foren von Umbraco angesprochen und es gibt mehrere Antworten, die Ihnen helfen können.

Siehe hier:

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

Im Wesentlichen können Sie ... nur ... aber erfordert einige Überlegungen, weil einige der Schlüsselklassen und Schnittstellen intern sind. Wie Lukas letzter Beitrag darauf hinweist, liegt das daran, dass die Funktionalität derzeit ein bewegliches Ziel ist.


0
2017-07-25 11:19