1

DotNetOpenAuth を使用する AccountController をテストしようとしていますが、問題が発生しています。Logon Actionresult をテストして、正しいビューが返されていることを確認したいと考えています。realm (私が思うに) には HttpContext.Current が null でないことを要求するコントラクトがあるため、テストは失敗します。どうにかしてリクエストをモックする必要があると思いますが、どうすればよいかわかりません。

これは ActionResult コードです。DotNetOpenAuth の例から直接取得したものです。

[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken]
public ActionResult LogOn(string openid_identifier, 
                          bool rememberMe, 
                          string returnUrl)
{
    Identifier userSuppliedIdentifier;
    if (Identifier.TryParse(openid_identifier, out userSuppliedIdentifier))
    {
        try
        {
            var request = this.RelyingParty
                              .CreateRequest(openid_identifier,
                                             Realm.AutoDetect, 
                                             Url.ActionFull("LogOnReturnTo"));

            if (!string.IsNullOrEmpty(returnUrl))
            {
                request.SetUntrustedCallbackArgument("returnUrl", returnUrl);
            }
            return request.RedirectingResponse.AsActionResult();
        }
        catch (ProtocolException ex)
        {
            ModelState.AddModelError("OpenID", ex.Message);
        }
    }
    else
    {
        ModelState.AddModelError("openid_identifier", 
                                 "This doesn't look like a valid OpenID.");
    }
    return RedirectToAction("LogOn", "Account");
}

前もって感謝します、

ピクルス

4

1 に答える 1

2

Controller の依存関係の 1 つで HttpContext.Current が利用可能である必要がある場合、それを直接モックすることはできませんが、その依存関係をテスト可能な抽象化自体にラップすることはできます。

Realmそれが原因であると仮定した場合、まずそこからインターフェースを抽出する必要があります。

public interface IRealm
{
    // I don't know what the real AutoDetect property returns,
    // so I just assume bool
    bool AutoDetect { get; }
}

明らかに、IRealm の実際の実装が必要になります。

public class RealmAdapter : IRealm
{
    bool AutoDetect { get { return Realm.AutoDetect; } }
}

たとえば、コンストラクター インジェクションを使用して、抽象 IRealm をコントローラーに挿入する必要があります。

public class MyController
{
    private readonly IRealm realm;

    public MyController(IRealm realm)
    {
        if( realm == null)
        {
            throw new ArgumentNullException("realm");
        }

        this.realm = realm;
    }
}

this.realmRealm クラスに直接依存する代わりに、使用する LogOn メソッドの実装を変更できるようになりました。

単体テストで、コントローラーにモック IRealm インスタンスを提供できるようになりました。

var realmMock = new Mock<IRealm>();
var sut = new MyController(realmMock.Object);

(この例では Moq を使用しています。)

于 2010-03-04T09:31:11.787 に答える