UrlHelper 类在 Asp.net mvc 中引发空异常

Posted

技术标签:

【中文标题】UrlHelper 类在 Asp.net mvc 中引发空异常【英文标题】:UrlHelper class throws null exception in Asp.net mvc 【发布时间】:2017-03-26 14:49:02 【问题描述】:

我正在开发一个 Asp.net mvc web 应用程序。我正在对我的应用程序进行单元测试。我正在使用 Moq 来模拟对象。我正在尝试模拟 Url 助手类。我找到了这个链接-asp.net mvc: how to mock Url.Content("~")?。使用该类,我可以在单元测试中模拟 UrlHelper 类。

我像这样创建了BaseController

public class BaseController : Controller

    private IUrlHelper _urlHelper;

    public new IUrlHelper Url
    
        get  return _urlHelper; 
        set  _urlHelper = value; 
    

这里是IUrlHelper 接口/抽象

public interface IUrlHelper

    string Action(string actionName);
    string Action(string actionName, object routeValues);
    string Action(string actionName, string controllerName);
    string Action(string actionName, RouteValueDictionary routeValues);
    string Action(string actionName, string controllerName, object routeValues);
    string Action(string actionName, string controllerName, RouteValueDictionary routeValues);
    string Action(string actionName, string controllerName, object routeValues, string protocol);
    string Action(string actionName, string controllerName, RouteValueDictionary routeValues, string protocol, string hostName);
    string Content(string contentPath);
    string Encode(string url);
    string RouteUrl(object routeValues);
    string RouteUrl(string routeName);
    string RouteUrl(RouteValueDictionary routeValues);
    string RouteUrl(string routeName, object routeValues);
    string RouteUrl(string routeName, RouteValueDictionary routeValues);
    string RouteUrl(string routeName, object routeValues, string protocol);
    string RouteUrl(string routeName, RouteValueDictionary routeValues, string protocol, string hostName);

我像这样在单元测试中模拟Url.Content()

Mock<IUrlHelper> urlHelperMock = new Mock<IUrlHelper>();
urlHelperMock
    .Setup(x => x.Content(It.IsAny<string>()))
    .Returns<string>(x => "~/" + x);// Mock Content method of Url Helper

测试运行成功并且工作正常。问题是我无法在实时应用程序中使用它。我的意思是当我运行我的应用程序并调用 Url.Content("path") 时,它会抛出 null 异常。

例如

public class ExampleController : BaseController

    public string GetPath()
    
       return Url.Content("~/Path/To/File");
    

Url.Content 在此代码中抛出空异常。它在单元测试中运行良好。如何修复该代码?

【问题讨论】:

这个例子展示了它如何模拟测试接口,但没有展示它是如何为生产代码实现的。很可能没有完成生产实现,因此对于实时执行它为空。 【参考方案1】:

在这种情况下,确实不需要抽象UrlHelper。只需模拟测试助手即可完成所需操作。

例如,假设

public class ExampleController : Controller 
    public string GetContent() 
       return Url.Content("~/Path/To/File");
    

这是一个使用 moq 模拟 UrlHelper 的测试,就像在原始示例中一样工作

[TestClass]
public class UrlHelperTest 
    [TestMethod]
    public void MockUrlHelper() 
        //Arrange            
        var expectedPath = "~/Path/To/File";
        var expectedContent = "<p>Fake content here<p>";
        var urlHelperMock = new Mock<UrlHelper>();
        urlHelperMock
            .Setup(m => m.Content(expectedPath))
            .Returns(expectedContent)
            .Verifiable();

        var sut = new ExampleController();
        sut.Url = urlHelperMock.Object; //Set mock UrlHelper        

        //Act
        var actualContent = sut.GetContent();

        //Assert
        urlHelperMock.Verify();
        Assert.AreEqual(expectedContent, actualContent);
    

所以现在可以执行测试,并且框架将在生产中填充必要的控制器属性,因为从技术上讲,从原始框架到自定义抽象没有任何改变。

【讨论】:

以上是关于UrlHelper 类在 Asp.net mvc 中引发空异常的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET MVC 中的控制器之外生成 URL?

ASP.NET + MVC5 入门完整教程七 -—-- MVC基本工具(上)

Asp.Net Mvc4 WebSecurity 如何激活或停用用户帐户

[Asp.Net Core]NET5_Razor扩展01

[Asp.Net Core]NET5_Razor扩展01

Entity Framework的学习(ASP.NET MVC5的学习中的一部分)