19

キャッスルウィンザーを使用していくつかのテストを実行しようとしています。テストの1つで、ウィンザーインストーラーを確認したいので、コンテナーがそのインターフェイスを指定してコンポーネントを解決できることを確認します。

これまでのところ、問題は、コンポーネントのインストーラーにPerWebRequestライフスタイルが含まれているときに始まります。最初は、HttpContext.Currentがnullであり、テストセットアップで偽のコンテキストを作成することで解決しました。nunitでこの例外が発生しています。テスト

System.Exception:httpモジュールCastle.MicroKernel.Lifestyle.PerWebRequestLifestyleModuleをweb.configのセクションに追加するのを忘れたようです。IIS7を統合モードで実行している場合は、IIS7を下のセクションに追加する必要があります。

これをNUnitから実行しているので、モジュールまたはクラスをウィンザーに登録して機能させる方法、またはこのテストは実際にはWebリクエストではなく、コンテナーが型を解決することを確認するだけで、モックする方法を教えてください。

また、実際のWebリクエストの外部でこのコンポーネントとの統合テストを行った場合にも同じことが起こります。これを機能させる方法や、このテストを実行できるようにWebリクエストを実際にモックする方法はありますか?

事前にトランク

ファー

4

4 に答える 4

21

テストでは、ComponentModelCreatedイベントをサブスクライブして、Webリクエストごとのコンポーネントのライフスタイルを別のものに変更できます。()。

単一のリクエストのスコープで統合テストを作成している場合は、singletonで実行する必要があります。

複数のリクエストにまたがる統合テストを作成している場合は、コンテキストライフスタイルを使用してリクエストの範囲をシミュレートできます。

編集:例のコードを含める(これはもう利用できません):

container.Kernel.ComponentModelCreated += Kernel_ComponentModelCreated;

…</p>

void Kernel_ComponentModelCreated(Castle.Core.ComponentModel model)
{
    if (model.LifestyleType == LifestyleType.Undefined)
        model.LifestyleType = LifestyleType.Transient;
}
于 2011-04-25T19:19:10.617 に答える
1

Castle.Facilities.AspNet.SystemWeb.WebRequestScopeAccessorウィンザーのバージョン5以降、PerWebRequestライフスタイルはすでにスコープ付きライフスタイルであるため、使用している場合、受け入れられた回答は機能しません。

ComponentModelCreatedデリゲートを次のように変更することで、機能するようになりました。

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

    if (model.ExtendedProperties.Contains(CastleScopeAccessorType))
    {
        model.ExtendedProperties.Remove(CastleScopeAccessorType);
    }
}
于 2019-06-19T06:51:05.317 に答える
1

私はこの拡張機能を実装することになりました。ATTN:PerWebRequestライフスタイルでコンポーネントをロードする前に呼び出す必要があります。

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

これらのインポートが必要です:

using System;
using System.Collections.Generic;
using Castle.Core;
using Castle.Facilities.AspNet.SystemWeb;
using Castle.Windsor;
于 2020-04-23T19:37:05.103 に答える
0

スコープのタイプがWebリクエストごとであるかどうかも確認したい場合は、これを行うこともできます

var isPerWebRequestScope = JsonConvert.SerializeObject(model.ExtendedProperties).Contains("Castle.Facilities.AspNet.SystemWeb.WebRequestScopeAccessor")
于 2019-06-12T11:51:42.393 に答える