簡體   English   中英

使用應用程序范圍變量的單元測試控制器

[英]Unit test controller that uses application scoped variables

我正在構建一個ASP.NET MVC4應用程序。 我沒有使用任何模擬框架,並且在可能的情況下,最好不要使用。 我的問題是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)在單元測試中,如何添加控制器所需的應用程序級別變量?

一般來說,全局變量不適合測試。 您至少可以采用兩種方法。

  1. 使用諸如Pex / Moles ,NMock等的模擬框架。

  2. 使用控制反轉方法( NInject是我的最愛)。 如果像控制器這樣的類具有外部依賴關系,則通常在其構造函數中請求接口。

    私有只讀IApplicationSettings _settings;

    公共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>();

這是應用程序范圍的變量用法的最佳實踐嗎?

最佳實踐有點主觀觀念,在沒有完全解釋您的情況以及您到底想達到什么目的的情況下,我不願討論它。

我們無法討論這是否是最佳做法,但從我的角度看,這也沒有錯。 沒錯,因為您正在使用允許對代碼進行單元測試的抽象。

在單元測試中,如何添加控制器所需的應用程序級別變量?

您可以使用諸如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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM