1

ASP.NETMVC4アプリを構築しています。私はモックフレームワークを使用していません。可能であれば、現時点では使用しないことをお勧めします。私の質問は2つの部分です。

Global.asaxで作成された変数を使用するコントローラーがあります。コントローラでは、このように変数にアクセスします。

HttpContext.Application["MyVar"]

1)これはアプリケーション全体の変数の使用法のベストプラクティスですか?そうでない場合、最善の方法は何ですか?

このコントローラーの単体テストを試みるために、次のコード(ここから)をテストメソッドに追加しました。

MyController target = new MyController();
var request = new HttpRequest("", "http://example.com/", "");
var response = new HttpResponse(System.IO.TextWriter.Null);
var httpContext = new HttpContextWrapper(new HttpContext(request, response));
target.ControllerContext = new ControllerContext(httpContext, new RouteData(), target);
target.ControllerContext.HttpContext.Application["MyVar"] = new MyVar();

問題は、アプリケーションに何も追加できないことです。コードの最後の行は何もしていないようで、コレクションは空のままです。VSのイミディエイトウィンドウでもこれを試しましたが、成功しませんでした。

2)単体テストで、コントローラーが必要とするアプリケーションレベルの変数を追加するにはどうすればよいですか?

4

2 に答える 2

1

一般に、グローバルはテストには適していません。少なくとも 2 つの方法があります。

  1. Pex/Moles、NMock などのモック フレームワークを使用します。

  2. 制御の反転アプローチを使用します ( NInjectが私のお気に入りです)。コントローラーのようなクラスに外部依存関係がある場合、通常はコンストラクターでインターフェイスを要求します。

    プライベート読み取り専用 IApplicationSettings _settings;

    public MyController(IApplicationSettings 設定) { _settings = 設定; }

    void someMethod() { _settings.Get("MyVar"); }

このようにして、実際の実装とテストの実装を作成できます。

public LiveAppSettings : IApplicationSettings
{
    public string Get(string key)
    { 
        return HttpContext.Current.Application[key];
    }
}

Ninject を使用すると、アプリケーションの起動時にいずれかの実装をバインドできます。

var kernel = new StandardKernel();
kernel.Bind<IApplicationSettings>().To<LiveAppSettings>();
于 2012-08-19T01:38:29.387 に答える
0

これは、アプリケーション全体で変数を使用するためのベスト プラクティスですか?

ベストプラクティスは少し主観的な概念であり、シナリオと正確に何を達成しようとしているのかを完全に説明することなく、私はそれについて議論したくありません.

これがベスト プラクティスであるかどうかについて議論することはできませんが、私が見る限り、それも間違っていません。コードの単体テストを可能にする抽象化を使用しているため、間違いではありません。

単体テストで、コントローラーが必要とするアプリケーション レベルの変数を追加するにはどうすればよいですか?

Rhino Mocks などのモック フレームワークを使用して、コントローラーが必要とする抽象化をモックすることができます。例として、次のコントローラーを見てみましょう。

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var myVar = (MyVar)HttpContext.Application["MyVar"];
        return Content(myVar.Foo);
    }
}

Index アクションの単体テストを行います。サンプル単体テストは次のとおりです。

[TestMethod]
public void Index_Action_Should_Retrieve_MyVal_From_AppState()
{
    // arrange
    var target = new HomeController();
    var httpContext = MockRepository.GeneratePartialMock<HttpContextBase>();
    var application = MockRepository.GeneratePartialMock<HttpApplicationStateBase>();
    application.Expect(x => x["MyVar"]).Return(new MyVar { Foo = "bar" });
    httpContext.Expect(x => x.Application).Return(application);
    target.ControllerContext = new ControllerContext(httpContext, new RouteData(), target);

    // act
    var actual = target.Index() as ContentResult;

    // assert
    Assert.AreEqual("bar", actual.Content);
}
于 2012-08-19T06:13:33.680 に答える