如何在使用VirtualPathUtility.GetAbsolute方法进行单元测试代码时模拟上下文 [英] How to mock context while unit testing code using VirtualPathUtility.GetAbsolute method

查看:116
本文介绍了如何在使用VirtualPathUtility.GetAbsolute方法进行单元测试代码时模拟上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用VirtualParthUtility.GetAbsolute的代码上运行单元测试,但是在模拟上下文以使其正常工作时遇到了问题.

I am running unit tests on code which uses VirtualParthUtility.GetAbsolute, but am having problems mocking the context for this to work.

我已经按照如下步骤与Moq建立了一个模拟上下文

I've set up a mock context with Moq as follows

    private Mock<HttpContextBase> MakeMockHttpContext(string url) // url = "~/"
    {
        var mockHttpContext = new Mock<HttpContextBase>();

        // Mock the request
        var mockRequest = new Mock<HttpRequestBase>();
        mockRequest.Setup(x => x.ApplicationPath).Returns("/");
        mockRequest.Setup(x => x.Path).Returns("/");
        mockRequest.Setup(x => x.PathInfo).Returns(string.Empty);
        mockRequest.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(url);

        mockHttpContext.Setup(x => x.Request).Returns(mockRequest.Object);

        // Mock the response
        var mockResponse = new Mock<HttpResponseBase>();
        mockResponse.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns((string s) => s);

        mockHttpContext.Setup(x => x.Response).Returns(mockResponse.Object);

        return mockHttpContext;
    }

并将其附加到MVC控制器

And attached this to an MVC Controller

_myController.ControllerContext = new ControllerContext(MakeMockHttpContext("~/").Object, new RouteData(), _slideSelectorController);

在测试过程中运行的代码如下:

The code that runs during the test hits the line:

venue.StyleSheetUrl = VirtualPathUtility.ToAbsolute(venue.StyleSheetUrl); // input like "~/styles/screen.css"

每次运行时,它都会进入System.Web.VirtualPathUtility,但要返回的"VirtualParthString"始终会引发异常:

Every time this runs, it steps into System.Web.VirtualPathUtility, with the problem that the "VirtualParthString" to be returned always throws an exception:

 public static string ToAbsolute(string virtualPath)
{
  return VirtualPath.CreateNonRelative(virtualPath).VirtualPathString;
}

在System.Web.VirtualPathString中很容易看到异常的原因:

The reason for the exception is easy to see in System.Web.VirtualPathString:

    public string VirtualPathString
{
  get
  {
    if (this._virtualPath == null)
    {
      if (HttpRuntime.AppDomainAppVirtualPathObject == null)
      {
        throw new HttpException(System.Web.SR.GetString("VirtualPath_CantMakeAppAbsolute", new object[] { this._appRelativeVirtualPath }));
      }
      if (this._appRelativeVirtualPath.Length == 1)
      {
        this._virtualPath = HttpRuntime.AppDomainAppVirtualPath;
      }
      else
      {
        this._virtualPath = HttpRuntime.AppDomainAppVirtualPathString + this._appRelativeVirtualPath.Substring(2);
      }
    }
    return this._virtualPath;
  }
}

通过监视"窗口,我可以看到_virtualPath和HttpRuntime.AppDomainAppVirtualPathString均为null,因此会引发异常.

Through the Watch Window I can see that _virtualPath and HttpRuntime.AppDomainAppVirtualPathString are both null, hence it throws an exception.

如果设置了_virtualPath,则不会发生异常.但是,在VirtualPath.Create方法创建了新的VirtualPath对象之后,它不会在返回_virtualPath属性之前对其进行设置.到目前为止,Create方法的摘录为:

If _virtualPath were set, the exception wouldn't happen. But after the VirtualPath.Create method has created a new VirtualPath object, it doesn't set the _virtualPath property before it is returned. An extract from the Create method up to this point is:

VirtualPath path = new VirtualPath();
  if (UrlPath.IsAppRelativePath(virtualPath))
  {
    virtualPath = UrlPath.ReduceVirtualPath(virtualPath);
    if (virtualPath[0] == '~')
    {
      if ((options & VirtualPathOptions.AllowAppRelativePath) == 0)
      {
        throw new ArgumentException(System.Web.SR.GetString("VirtualPath_AllowAppRelativePath", new object[] { virtualPath }));
      }
      path._appRelativeVirtualPath = virtualPath;
      return path;

因此,如果有人可以建议如何进行此单元测试,那将非常有帮助!

So if anyone can suggest how to get this unit test working, that will be very helpful!

谢谢

史蒂夫

推荐答案

我只是创建一个包装器接口.像这样:

I would just create a wrapper interface. Something like:

public interface IPathUtilities
{
    string ToAbsolute(string virtualPath);
}

您可以将其注入到控制器中.在测试时,请使用存根.在运行时,您将拥有一个实现IPathUtilities并调用VirtualPathUtility.ToAbsolute()的类.

You can inject that into your controller. At test time, use a stub. At runtime, you'll have a class that implements IPathUtilities and calls VirtualPathUtility.ToAbsolute().

这篇关于如何在使用VirtualPathUtility.GetAbsolute方法进行单元测试代码时模拟上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆