FormsAuthentication.SignOut()の実行を許可するには、HttpContextで何が必要ですか?

StackOverflow https://stackoverflow.com/questions/1430180

  •  07-07-2019
  •  | 
  •  

質問

ログアウトメソッドの単体テストを作成しようとしています。とりわけ FormsAuthentication.SignOut()です。ただし、 System.NullReferenceException がスローされます。

モックを作成しました。 HttpContext (Moqを使用)ですが、明らかに何かが欠落しています。

私のモックコンテキストには以下が含まれます:

  • Request
  • の模擬 HttpRequestBase
  • Response
  • の偽装 HttpResponseBase
  • Request.Cookies HttpCookieCollection Response.Cookies
  • の別の
  • User
  • での模擬 IPrincipal

ラッパールートに移動し、その場所に空の FormsAuth ラッパーオブジェクトを挿入できることは承知していますが、1行を修正するためだけに3つの追加ファイルを避けたいと思います。コード。それと私はまだ答えが欲しいです

だから私の質問は" HttpContext FormsAuthentication.SignOut()を実行できるようにするために必要なもの "

役に立ちましたか?

解決

ログアウトのコードは次のとおりです。

public static void SignOut()
{
    Initialize();
    HttpContext current = HttpContext.Current;
    bool flag = current.CookielessHelper.DoesCookieValueExistInOriginal('F');
    current.CookielessHelper.SetCookieValue('F', null);
    if (!CookielessHelperClass.UseCookieless(current, false, CookieMode) || current.Request.Browser.Cookies)
    {
        string str = string.Empty;
        if (current.Request.Browser["supportsEmptyStringInCookieValue"] == "false")
        {
            str = "NoCookie";
        }
        HttpCookie cookie = new HttpCookie(FormsCookieName, str);
        cookie.HttpOnly = true;
        cookie.Path = _FormsCookiePath;
        cookie.Expires = new DateTime(0x7cf, 10, 12);
        cookie.Secure = _RequireSSL;
        if (_CookieDomain != null)
        {
            cookie.Domain = _CookieDomain;
        }
        current.Response.Cookies.RemoveCookie(FormsCookieName);
        current.Response.Cookies.Add(cookie);
    }
    if (flag)
    {
        current.Response.Redirect(GetLoginPage(null), false);
    }
}

CookielessHelperClassインスタンスが必要なようです。残念なことに、それは内部で密封されています-TypeMockを使用していない限り、それをモックする方法はありません。ラッパーの提案については+1:)

他のヒント

この場合のNullReferenceExceptionは、実際には呼び出しによってスローされています:

current.Request.Browser["supportsEmptyStringInCookieValue"]

次の呼び出しにより、このアサーションをテストできます。

HttpContext.Current.Request.Browser.SupportsEmptyStringInCookieValue

... NullReferenceExceptionも返します。あなたが電話しようとすると、受け入れられた答えに反して:

CookielessHelperClass.UseCookieless(current, false, CookieMode)

...イミディエイトウィンドウから、これはエラーなしで戻ります。

次のように例外を修正できます:

HttpContext.Current.Request.Browser = new HttpBrowserCapabilities() { Capabilities = new Dictionary<string, string> { { "supportsEmptyStringInCookieValue", "false" } } };

...および FormsAuthentication.SignOut()呼び出しは成功します。

FormsAuthentication.SignOut()をいつでも別のメソッドにラップし、スタブ/モックすることができます。

IFormsAuthenticationWrapインターフェースを作成します。

public interface IFormsAuthenticationWrap
{
    void SignOut();
}

IFormsAuthenticationWrapを実装するラップクラスを作成します

public class FormsAuthenticationWrap : IFormsAuthenticationWrap
{
    public void SignOut()
    {
        FormsAuthentication.SignOut();
    }
}

呼び出し元のクラスは次のようになります。

public class LogOutClass
{
    private readonly IFormsAuthenticationWrap _formsAuthentication;

    public LogOutClass() : this (new FormsAuthenticationWrap())
    {
    }

    public LogOutClass(IFormsAuthenticationWrap formsAuthentication)
    {
        _formsAuthentication = formsAuthentication;
    }

    public void LogOutMethod()
    {
        // Code before SignOut

        _formsAuthentication.SignOut();

        // Code after SignOut
    }
}

次に、テストに取り掛かりましょう。 Moqでスタブ/モックできますが、ここでは手動で行う方法を示します。 スタブ/モッククラスを作成します。

public class FormsAuthenticationStub : IFormsAuthenticationWrap
{
    public void SignOut()
    {
    }
}

そして最後にテストを書きます:

    [TestMethod]
    public void TestLogOutMethod()
    {
        var logOutClass = new LogOutClass(new FormsAuthenticationStub());
        logOutClass.LogOutMethod();
    }

ラッパーはクリーンな方法です。

「これは非常に大きなアプリケーションになるだろう」というコメントで、あなたは反対のラッパーを使用する別の引数です。大きなアプリケーションでは、明確な依存関係が必要であり、テストを簡単に行う必要があります。

テスト中のasp.netの内部動作にあいまいな依存関係を介して簡単に注入できるクリーンな依存関係を取引しています。


別のメモ:リフレクターを使用。正直なところ、asp.netのこの特定の部分の内部依存関係はわかりませんが、リフレクターを使用して疑問点をクリアできます。

HttpContextをモックしないで、テストで実際のものを使用してください。このように、これらのすべてのHttp *のものをモックする必要はありません。 Ivonna を使用して、これらの依存関係をすべてモックし、不可解な例外を取得することなく、メソッドを直接テストできます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top