使用应用程序单元测试控制器作用域的变量(Unit test controller that uses

2019-07-31 01:39发布

我建立一个ASP.NET应用程序MVC4。 我没有使用任何嘲弄的框架,如果可能的话,在这一点上不喜欢。 我的问题是两个部分。

我有一个使用在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)在单元测试中,我怎样才能添加应用程序级的变量控制器的需求?

Answer 1:

一般来说全局都不好进行测试。 还有,你可能至少需要两种方法。

  1. 使用像模拟框架的Pex /痣 ,NMock等。

  2. 使用反转的控制的方法( NInject是我的最爱)。 如果像控制器类具有外部依赖性,它要求的界面,典型地在其构造。

    私人只读IApplicationSettings _settings;

    公共myController的(IApplicationSettings设置){_settings =设置; } }

    空隙的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>();


Answer 2:

这是一个最佳实践的应用程序范围变量的使用?

最好的做法是有点主观的概念,并没有完全解释您的情况,什么恰恰是你想实现我不想讨论这个问题。

我们可以不讨论这是否是最好的做法,但是从我可以看到它是没有错无论是。 这是因为你使用的是抽象,允许代码进行单元测试是没有错的。

在单元测试中,我该怎么添加应用程序级的变量控制器的需求呢?

你可以使用一个模拟框架,如犀牛嘲笑嘲笑抽象控制器的需求。 让我们以一个例子如下控制器:

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

我们希望进行单元测试索引操作。 下面是一个示例单元测试:

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


文章来源: Unit test controller that uses application scoped variables