当我开始了解模拟和不同的框架的时候,我只是在学习如何为我的asp.net mvc提供单元测试。
经过检查,我发现MOQ似乎是最容易得到的。到目前为止,我还在试图嘲弄Request.ServerVariables,作为看完这篇文章后,我已经了解到最好将它们抽象为属性。
因此:
/// <summary>
/// Return the server port
/// </summary>
protected string ServerPort
{
get
{
return Request.ServerVariables.Get("SERVER_PORT");
}
}但我很难学会如何正确地嘲弄这一切。我有一个家庭控制器ActionResult函数,它获取用户服务器信息,然后创建一个表单来获取用户的信息。
我试着使用hanselman的mvcmockhelpers类,但我不知道如何使用它。
这就是我目前所拥有的..。
[Test]
public void Create_Redirects_To_ProductAdded_On_Success()
{
FakeViewEngine engine = new FakeViewEngine();
HomeController controller = new HomeController();
controller.ViewEngine = engine;
MvcMockHelpers.SetFakeControllerContext(controller);
controller.Create();
var results = controller.Create();
var typedResults = results as RedirectToRouteResult;
Assert.AreEqual("", typedResults.RouteValues["action"], "Wrong action");
Assert.AreEqual("", typedResults.RouteValues["controller"], "Wrong controller");
}问题:
发布于 2010-05-05 07:38:53
基本上,我输入了所有的引用,并使用这个函数,我能够让它正常工作。我还没有使用mvcmockhelpers课程,因为我还在努力学习这一切。
对于那些对我如何解决这个问题感兴趣的人来说,这就是我使用的代码。
[Test]
public void Create_Returns_ViewResult_On_Success()
{
var server = new Mock<HttpServerUtilityBase>(MockBehavior.Loose);
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.Setup(x => x.ApplicationPath).Returns("/");
request.Setup(x => x.Url).Returns(new Uri("http://localhost"));
request.Setup(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection{
{ "SERVER_NAME", "localhost" },
{ "SCRIPT_NAME", "localhost" },
{ "SERVER_PORT", "80" },
{ "HTTPS", "www.melaos.com" },
{ "REMOTE_ADDR", "127.0.0.1" },
{ "REMOTE_HOST", "127.0.0.1" }
});
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
context.SetupGet(x => x.Server).Returns(server.Object);
var controller = new HomeController();
//MvcMockHelpers.SetFakeControllerContext(controller);
controller.ControllerContext = new ControllerContext(context. Object, new RouteData(), controller);
var results = controller.Create();
Assert.IsNotNull(results);
Assert.IsInstanceOf(typeof(ViewResult), results);
}发布于 2016-10-27 06:47:12
由于我想要模拟HttpContext,而不是HttpContextBase,所以我试图找到一种将HttpContextBase模拟对象转换为HttpContext的方法,发现这是不可能的。
HttpContext 这是老式的asp.net上下文。这方面的问题是,它没有基类,也不是虚拟的,因此无法用于测试(不能模拟它)。建议不要将其作为函数参数传递,而是传递类型为HttpContextBase的变量。 HttpContextBase 这是( c# 3.5的新版本)对HttpContext的替代。因为它是抽象的,所以它现在是可以模仿的。这样做的想法是,您的函数如果希望通过上下文,就应该接收其中的一个。它由HttpContextWrapper具体实现。 HttpContextWrapper 在C# 3.5中也是新的--这是HttpContextBase的具体实现。若要在普通网页中创建其中之一,请使用新HttpContextWrapper(HttpContext.Current)。 为了使您的代码单元可测试,您可以将所有变量和函数参数声明为HttpContextBase类型,并使用IOC框架(如Castle )将其注入。在普通代码中,城堡是注入相当于“新HttpContextWrapper(HttpContext.Current)”的代码,而在测试代码中则是对HttpContextBase的模拟。 (资料来源:http://www.splinter.com.au/httpcontext-vs-httpcontextbase-vs-httpcontext/)
所以我改变了调用代码的方式。
使用HttpContext
public static string GetIpAddress(HttpContext currentContext) {
...
}使用HttpContextBase
public static string GetIpAddress(HttpContextBase currentContext) {
...
}当我使用这个方法时,我用HttpContextWrapper包装HttpContext,如下所示:
var ip = GeneralUtil.GetIpAddress(new HttpContextWrapper(HttpContext.Current));现在,您可以通过以下HttpContextBase轻松地模拟丹·阿特金森的回答
https://stackoverflow.com/questions/2770265
复制相似问题