我正在尝试在我的MVC应用程序上运行一些测试,但是我一直在经历一个让它无法运行的世界。我会尽力做到这一点:
我正在使用RhinoMocks尝试这样的事情:
设定:
MockRepository mocks = new MockRepository();
HttpContextBase _mockContext = mocks.FakeHttpContext();
mocks.SetFakeControllerContext(new LoginController());
HttpApplicationStateBase appState = MockRepository.GenerateStub<HttpApplicationStateBase>();
_mockContext.Expect(mc => mc.Application).Return(appState);
HttpContext.Current = _mockContext.ApplicationInstance.Context;
以下是FakeHttpContext()
方法:
public static HttpContextBase FakeHttpContext(this MockRepository mocks)
{
HttpApplication app = mocks.PartialMock<HttpApplication>();
HttpContextBase context = mocks.PartialMock<HttpContextBase>();
HttpRequestBase request = mocks.PartialMock<HttpRequestBase>();
HttpResponseBase response = mocks.PartialMock<HttpResponseBase>();
HttpSessionStateBase session = mocks.PartialMock<HttpSessionStateBase>();
HttpServerUtilityBase server = mocks.PartialMock<HttpServerUtilityBase>();
SetupResult.For(context.ApplicationInstance).Return(app);
SetupResult.For(context.Request).Return(request);
SetupResult.For(context.Response).Return(response);
SetupResult.For(context.Session).Return(session);
SetupResult.For(context.Server).Return(server);
mocks.Replay(context);
return context;
}
我确实需要访问HttpContextBase.Request.AppRelativeCurrentExecutionFilePath
,但它始终以null
的形式返回。 HttpContext.Current.Request.RequestContext
也是如此。
有人可以帮我吗?可以肯定地说,我现在很绝望。
答案 0 :(得分:1)
为什么不创建一个包含对HttpContext基础的调用的抽象类?
然后你可以这样做:
public class MyClass
{
private readonly IHttpContext _httpContext;
MyClass(IHttpContext httpContext)
{
_httpContext = httpContext;
}
public void Blaat()
{
_httpContext.DoYourThingsWithTheHttpContext();
}
}
假设您正在使用依赖注入,否则请查看Microsoft的Fakes and Stubs框架。
答案 1 :(得分:1)
首先,尝试避免使用HttpContext.Current,因为使用静态方法会使测试变得更加困难,因为您现在已经发现了。如果您使用的是依赖注入框架,请将HttpContextBase注入构造函数。
对于您的实际问题,请在FakeHttpContext()
尝试更改
HttpRequestBase request = mocks.PartialMock<HttpRequestBase>();
到
HttpRequestBase request = mocks.GenerateStub<HttpRequestBase>();
然后在你的测试中你可以做这样的事情:
_mockContext.Request.Stub(x=> x.AppRelativeCurrentExecutionFilePath).Return("foo");
var result = object.DoSomething();
Assert.AreEqual("foo",result);
我不认为对HttpContext进行部分模拟是非常有用的,因为您将测试框架(即测试框架根据HttpContext中的值Y和Z返回正确的值X)
另一种方法是在HttpContextBase周围创建一个包装类,它将返回计算值。例如。 HttpContextBaseWrapper.AppRelativeCurrentExecutionFilePath()
,HttpContextBaseWrapper.RequestIpAddress()
。这将使你所有其他类的测试变得不那么复杂,因为他们不必担心模拟HttpContextBase和细节,他们只需要模拟你的HttpContextBaseWrapper类。
修改强>
我还建议你注入你的HttpRequestContext,但是如果那不可能那么你可以在FakeHttpContext
方法中存储RequestContext:
var requestContext = MockRepository.GenerateStub<RequestContext>();
request.RequestContext = requestContext;