asp.net-mvc - 单元测试 Url.Action(使用 Rhino Mocks?)

标签 asp.net-mvc unit-testing rhino-mocks urlhelper

我正在尝试为这样使用的 UrlHelper 扩展方法编写测试:

Url.Action<TestController>(x => x.TestAction());

但是,我似乎无法正确设置它,以便我可以创建一个新的 UrlHelper,然后断言返回的 url 是预期的。这就是我所拥有的,但我对任何不涉及 mock 的事情都持开放态度。 ;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") 但无论如何它都会失败,所以我知道这不是我的扩展方法不起作用。 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 模拟的 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 的单元测试通过。我试过了,它奏效了。希望这会有所帮助。

关于asp.net-mvc - 单元测试 Url.Action(使用 Rhino Mocks?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/951329/

相关文章:

c# - 在 httppost 之后关闭模式窗口

asp.net-mvc - 使用 ASP.NET MVC 在 jquery 中调用 getJSON 时出错

javascript - 如何在angular 2中使用多个组件

android - 如何从使用 PowerMockRunner 运行的 android 单元测试加载 json 文件?

c# - 使用 Rhino Mocks 模拟阻塞调用

c# - CaSTLe DynamicProxy - 创建涉及用作 GTR 的 GTP 的代理时失败

.net - rhino-mocks - 很好的示例应用程序

c# - MVC 5 经过身份验证的用户正在注销,没有 "remember me"(ExpireTimeSpan/MachineKey/Session Timeout)

unit-testing - 您如何对使用计时器的 Rx 运算符进行单元测试?

java - Infinispan缓存在悲观模式下不会抛出异常