gpt4 book ai didi

asp.net-mvc - 使用 Moq 模拟 HttpContextBase

转载 作者:行者123 更新时间:2023-12-02 23:41:50 29 4
gpt4 key购买 nike

我有一个单元测试装置,我试图在 ASP.NET MVC Controller 上测试 ControllerAction,该 Controller 用于 Web 应用程序上的成员函数。我正在尝试模拟 HttpContext 进行测试。测试中的 ControllerAction 实际上在 HttpContext 上设置属性,例如 Session 值、Response.Cookies 值等。这不是全部代码,但这里是我尝试运行的测试的粗略示例:

[Test]
public void ValidRegistrationDataSuccessfullyCreatesAndRegistersUser()
{
var context = new Mock<HttpContextBase>() {DefaultValue = DefaultValue.Mock};
context.SetupAllProperties();
var provider = new Mock<MembershipProvider>(new object[] {context.Object});
var controller = new AccountController(context.Object, provider.Object);
// This just sets up a local FormCollection object with valid user data
// in it to use to attempt the registration
InitializeValidFormData();
ActionResult result = controller.Register(_registrationData);
Assert.IsInstanceOfType(typeof(ViewResult), result);
// Here is where I'd like to attempt to do Assertions against properties
// of the HttpContext, like ensuring that a Session object called "User"
// exists, and new auth cookie exists on the Response.Cookies collection.
// So far I've been unable to successfully check the values of those properties.
// I've been unsuccessful in getting those properties setup correctly on my
// mock object so that my ControllerAction can actually *set* their values,
// and that I can make assertions on them afterwards. The above code actually
// generates a StackOverflowException (which I've reported) on the
// context.SetupAllProperties() call. What am I doing wrong, or what do I need
// to do to be able to set and assert on those context properties?
}

不确定我做错了什么,但如果有人能指出我正确的方向并向我展示如何设置这个模拟 HttpContextBase 对象,以便我的 Controller 实际上可以在其属性上设置值,我会很高兴我可以对这些属性进行断言,以确保我的 ControllerAction 正在执行我需要的操作。

我处理这个问题的方式是错误的吗?我知道 MVC Controller 有一个 ControllerContext,我可以用它来设置 Session 等的值,但我无法弄清楚如何在不注入(inject)它的情况下模拟类似的东西。有什么办法可以代替吗? (我还需要能够将上下文传递给我的 MembershipProvider)这是更好的方法吗?

谢谢。

最佳答案

我正在使用 Steve Sanderson 的 Pro Asp.NET MVC book 中包含的一些代码的版本...我目前面临道德困境,是否可以在此处发布代码。我是否可以妥协于高度精简的版本? ;)

因此,这可以很容易地重用,创建一个类似于下面的类,您将传递给 Controller ​​。这将设置您的模拟并将它们设置到 Controller 的 ControllerContext

public class ContextMocks
{
public Moq.Mock<HttpContextBase> HttpContext { get; set; }
public Moq.Mock<HttpRequestBase> Request { get; set; }
public RouteData RouteData { get; set; }

public ContextMocks(Controller controller)
{
//define context objects
HttpContext = new Moq.Mock<HttpContextBase>();
HttpContext.Setup(x => x.Request).Returns(Request.Object);
//you would setup Response, Session, etc similarly with either mocks or fakes

//apply context to controller
RequestContext rc = new RequestContext(HttpContext.Object, new RouteData());
controller.ControllerContext = new ControllerContext(rc, controller);
}
}

然后在您的测试方法中,您只需创建一个 ContextMocks 实例并传入您正在测试的 Controller 对象:

[Test]
Public void test()
{
var mocks = new ContextMocks(controller);
var req = controller.Request;
//do some asserts on Request object
}

看起来与 Craig 的示例非常相似,但这是使用 Moq v3 的。我必须为此向 Steve Sanderson 表示支持 - 我使用它作为测试各种传统上难以测试的东西的基础:cookie、 session 、请求方法、查询字符串等等!

关于asp.net-mvc - 使用 Moq 模拟 HttpContextBase,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1228179/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com