19 Stimmen

Testen der Castle windsor-Komponente mit PerWebRequest-Lifestyle

Ich versuche, einige Tests mit Schloss windsor beteiligt zu tun, in einem meiner Tests möchte ich die windsor-Installateure zu überprüfen, so dass ich überprüfen, dass der Container meine Komponenten gegeben seine Schnittstelle auflösen kann.

So weit, so gut, das Problem beginnt, wenn die Komponente PerWebRequest Lebensstil in seinem Installateur hat, auf den ersten beschwerte es über HttpContext.Current ist null, nachdem, dass man gelöst Erstellen einer gefälschten Kontext in Test-Setup ich bin jetzt mit dieser Ausnahme in Nunit-Test

System.Exception : Sieht aus, als hätten Sie vergessen, das http-Modul Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule zu registrieren Fügen Sie '' zu dem Abschnitt in Ihrer web.config hinzu. Wenn Sie IIS7 im integrierten Modus betreiben, müssen Sie es zum Abschnitt unter

Da ich dies von NUnit ausführen, wie ich das Modul oder die Klasse in Windsor registrieren kann, so dass es funktioniert, oder wie kann gespottet werden, wie in diesem Test ist nicht wirklich eine Web-Anfrage, nur überprüfen, dass der Container den Typ auflösen.

Und auch diese gleiche Sache wird passieren, wenn ich alle Integrationstests mit dieser Komponente außerhalb einer realen Webanforderung machen, gibt es irgendeine Möglichkeit, diese Arbeit zu machen oder wirklich eine Web-Anforderung spiegeln, so dass diese Tests ausgeführt werden können?

Tranchen im Voraus

Fer

1 Stimmen

Ich habe gestern eine ähnliche Frage gestellt unter stackoverflow.com/questions/5772497/

21voto

Mauricio Scheffer Punkte 97391

In Ihrem Test könnten Sie das ComponentModelCreated-Ereignis abonnieren und den Lebensstil Ihrer Komponenten pro Web-Anfrage auf etwas anderes ändern. ( Beispiel ).

Wenn Sie einen Integrationstest mit dem Umfang einer einzelnen Anfrage schreiben, sollte Singleton ausreichen.

Wenn Sie einen Integrationstest schreiben, der sich über mehrere Anfragen erstreckt, können Sie eine kontextueller Lebensstil um den Umfang der Anfragen zu simulieren.

Bearbeiten: Einschließlich Code aus dem Beispiel (das nicht mehr verfügbar ist):

container.Kernel.ComponentModelCreated += Kernel_ComponentModelCreated;

void Kernel_ComponentModelCreated(Castle.Core.ComponentModel model)
{
    if (model.LifestyleType == LifestyleType.Undefined)
        model.LifestyleType = LifestyleType.Transient;
}

1voto

Reasurria Punkte 1578

Ab Version 5 von Windsor funktioniert die akzeptierte Antwort nicht mehr, wenn Sie mit Castle.Facilities.AspNet.SystemWeb.WebRequestScopeAccessor weil der Lebensstil "PerWebRequest" bereits ein "scoped lifestyle" ist.

Ich habe es zum Laufen gebracht, indem ich die ComponentModelCreated an folgende Personen delegieren:

void Kernel_ComponentModelCreated(Castle.Core.ComponentModel model)
{
    const string CastleScopeAccessorType = "castle.scope-accessor-type";

    if (model.ExtendedProperties.Contains(CastleScopeAccessorType))
    {
        model.ExtendedProperties.Remove(CastleScopeAccessorType);
    }
}

1voto

Alex Akhtyrskiy Punkte 21

Ich habe diese Erweiterung schließlich implementiert. ATTN: Muss anrufen vor Ladekomponenten mit dem PerWebRequest Lebensstil:

public static class WindsorContainerExtensions
{
    public static IWindsorContainer OverridePerWebRequestLifestyle(this IWindsorContainer container)
    {
        container.Kernel.ComponentModelCreated += model =>
        {
            if (model.IsPerWebRequestLifestyle())
            {
                model.LifestyleType = LifestyleType.Transient;
            }
        };

        return container;
    }

    private static bool IsPerWebRequestLifestyle(this ComponentModel model)
    {
        return model.LifestyleType == LifestyleType.Scoped
            && model.HasAccessorType(typeof(WebRequestScopeAccessor));
    }

    private static bool HasAccessorType(this ComponentModel model, Type type)
        => model.HasExtendedProperty("castle.scope-accessor-type", type);

    private static bool HasExtendedProperty<T>(this ComponentModel model, object key, T expected)
    {
        return model.ExtendedProperties[key] is T actual
            && EqualityComparer<T>.Default.Equals(actual, expected);
    }
}

Erfordert diese Importe:

using System;
using System.Collections.Generic;
using Castle.Core;
using Castle.Facilities.AspNet.SystemWeb;
using Castle.Windsor;

0voto

kernowcode Punkte 5194

Wenn Sie auch prüfen möchten, ob der Geltungsbereich per Webanforderung festgelegt wurde, können Sie auch Folgendes tun

var isPerWebRequestScope = JsonConvert.SerializeObject(model.ExtendedProperties).Contains("Castle.Facilities.AspNet.SystemWeb.WebRequestScopeAccessor")

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X