我试图为UrlHelper扩展方法编写一个测试,这个方法是这样使用的:
- Url.Action<TestController>(x => x.TestAction());
但是,我无法正确设置,以便我可以创建一个新的UrlHelper,然后断言返回的URL是预期的.这是我所拥有的,但我对任何不涉及嘲笑的东西都是开放的. ; O)
- [Test]
- public void Should_return_Test_slash_TestAction()
- {
- // Arrange
- RouteTable.Routes.Add("TestRoute",new Route("{controller}/{action}",new MvcRouteHandler()));
- var mocks = new MockRepository();
- var context = mocks.FakeHttpContext(); // the extension from hanselman
- var helper = new UrlHelper(new RequestContext(context,new RouteData()),RouteTable.Routes);
- // Act
- var result = helper.Action<TestController>(x => x.TestAction());
- // Assert
- Assert.That(result,Is.EqualTo("Test/TestAction"));
- }
我尝试将其更改为urlHelper.Action(“Test”,“TestAction”),但它会失败,所以我知道这不是我的extensionmethod不工作. NUnit返回:
- NUnit.Framework.AssertionException: Expected string length 15 but was 0. Strings differ at index 0.
- Expected: "Test/TestAction"
- But was: <string.Empty>
我已经验证路由是注册和工作,我正在使用Hanselmans扩展来创建一个假HttpContext.以下是我的UrlHelper扩展方法:
- public static string Action<TController>(this UrlHelper urlHelper,Expression<Func<TController,object>> actionExpression) where TController : Controller
- {
- var controllerName = typeof(TController).GetControllerName();
- var actionName = actionExpression.GetActionName();
- return urlHelper.Action(actionName,controllerName);
- }
- public static string GetControllerName(this Type controllerType)
- {
- return controllerType.Name.Replace("Controller",string.Empty);
- }
- public static string GetActionName(this LambdaExpression actionExpression)
- {
- return ((MethodCallExpression)actionExpression.Body).Method.Name;
- }
任何想法,我失踪了,让它工作?
/克里斯托弗
解决方法
它不工作的原因是RouteCollection对象在内部调用HttpResponseBase上的ApplyAppPathModifier方法.看起来Hanselman的模拟代码没有对该方法设置任何期望,所以它返回null,这就是为什么你所有的调用UrlHelper上的Action方法都返回一个空字符串的原因.该修复将是在HttpResponseBase mock的ApplyAppPathModifier方法上设置一个期望,以返回传递给它的值.我不是Rhino Mocks的专家,所以我不完全确定语法.如果您正在使用Moq,那么它将如下所示:
- httpResponse.Setup(r => r.ApplyAppPathModifier(It.IsAny<string>()))
- .Returns((string s) => s);
或者,如果你只是使用一个手工制作的模拟,这样的工作:
- internal class FakeHttpContext : HttpContextBase
- {
- private HttpRequestBase _request;
- private HttpResponseBase _response;
- public FakeHttpContext()
- {
- _request = new FakeHttpRequest();
- _response = new FakeHttpResponse();
- }
- public override HttpRequestBase Request
- {
- get { return _request; }
- }
- public override HttpResponseBase Response
- {
- get { return _response; }
- }
- }
- internal class FakeHttpResponse : HttpResponseBase
- {
- public override string ApplyAppPathModifier(string virtualPath)
- {
- return virtualPath;
- }
- }
- internal class FakeHttpRequest : HttpRequestBase
- {
- private NameValueCollection _serverVariables = new NameValueCollection();
- public override string ApplicationPath
- {
- get { return "/"; }
- }
- public override NameValueCollection ServerVariables
- {
- get { return _serverVariables; }
- }
- }
上述代码应该是HttpContextBase的最小必要实现,以便对UrlHelper进行单元测试通过.我试过了,它的工作.希望这可以帮助.