UrlHelper模拟不起作用



我试图写一个单元测试,但我的测试调用的方法,调用另一个方法,使用UrlHelper类生成一个URL。调用urlHelper.Action的结果一直返回null

我试过模拟(使用Moq)所有的组件,我认为这个控制器将需要能够得到这个工作,但我仍然得到null

单元测试类

[TestFixtureSetUp]
public void Configure_Defaults()
{
    var mockHttpContextBase = new Mock<HttpContextBase>();
    var mockRequest = new Mock<HttpRequestBase>();
    var mockControllerContext = new Mock<ControllerContext>();
    var mockWebRoutingRequestContrext = new Mock<RequestContext>();
    mockRequest
        .Setup(request => request.Url)
        .Returns(new Uri("http://dev.fleepos.local/Register"));
    mockHttpContextBase
        .Setup(httpContext => httpContext.Request)
        .Returns(mockRequest.Object);
    mockWebRoutingRequestContrext
        .Setup(request => request.HttpContext)
        .Returns(mockHttpContextBase.Object);
    mockWebRoutingRequestContrext
        .Setup(request => request.RouteData)
        .Returns(new RouteData());
    var urlHelper = new UrlHelper(mockWebRoutingRequestContrext.Object);
    mockControllerContext
        .Setup(controllerContext => controllerContext.HttpContext)
        .Returns(mockHttpContextBase.Object);

    _registerController = new RegisterController() {ControllerContext = mockControllerContext.Object, Url = urlHelper};
}
[Test]
public void Display_Validate_Account_Page_On_Successful_Registration()
{
    //act
    var result = (RedirectToRouteResult)_registerController.Register(_userRegisterationViewModel);
    //assert
    Assert.That(result.RouteValues["action"], Is.EqualTo("ValidateAccount"));
}

控制器动作调用的控制器方法

private string GenerateActionLink(string actionName, string token, string username)
{
    string validationLink = null;
    if (Request.Url != null)
    {
        var urlHelper = new UrlHelper(ControllerContext.RequestContext);
        validationLink = urlHelper.Action(actionName, "Register",
            new { Token = token, Username = username },
            Request.Url.Scheme);
    }
    return validationLink;
}

控制器已经有一个UrlHelper Url属性,可以模拟做你想做的事情。通过在控制器操作调用的控制器方法中创建new UrlHelper,就失去了替换mock/fake的机会。

首先更新控制器操作调用的控制器方法,使其测试友好

private string GenerateActionLink(string actionName, string token, string username) {
    string validationLink = null;
    if (Request.Url != null) {
        validationLink = Url.Action(actionName, "Register",
            new { Token = token, Username = username },
            Request.Url.Scheme);
    }
    return validationLink;
}

现在有更多的控制控制器的UrlHelper。UrlHelper也可以被模拟并传递给控制器上下文

这是上面解释的一个最小的完整示例。

[TestClass]
public class UrlHelperTest {
    [TestMethod]
    public void MockUrlHelper() {
        //Arrange
        var requestUrl = new Uri("http://myrequesturl");
        var request = Mock.Of<HttpRequestBase>();
        var requestMock = Mock.Get(request);
        requestMock.Setup(m => m.Url).Returns(requestUrl);
        var httpcontext = Mock.Of<HttpContextBase>();
        var httpcontextSetup = Mock.Get(httpcontext);
        httpcontextSetup.Setup(m => m.Request).Returns(request);

        var actionName = "MyTargetActionName";
        var expectedUrl = "http://myfakeactionurl.com";
        var mockUrlHelper = new Mock<UrlHelper>();
        mockUrlHelper
            .Setup(m => m.Action(actionName, "Register", It.IsAny<object>(), It.IsAny<string>()))
            .Returns(expectedUrl)
            .Verifiable();
        var sut = new MyController();
        sut.Url = mockUrlHelper.Object;
        sut.ControllerContext = new ControllerContext {
            Controller = sut,
            HttpContext = httpcontext,
        };
        //Act
        var result = sut.MyAction();
        //Assert
        mockUrlHelper.Verify();
    }
    public class MyController : Controller {
        [HttpPost]
        public ActionResult MyAction() {
            var link = GenerateActionLink("MyTargetActionName", string.Empty, string.Empty);
            return View((object)link);
        }
        private string GenerateActionLink(string actionName, string token, string username) {
            string validationLink = null;
            if (Request.Url != null) {
                var encodedToken = EncodedUrlParameter(token);
                var url = Url.Action(actionName, "Register", new { Token = encodedToken, Username = username }, Request.Url.Scheme);
                validationLink = url;
            }
            return validationLink;
        }
        private string EncodedUrlParameter(string token) {
            return "Fake encoding";
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新