加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 控制器中的模拟服务器

发布时间:2020-12-15 22:32:15 所属栏目:asp.Net 来源:网络整理
导读:我的控制器中有以下行: string lTempPath = Path.Combine(Server.MapPath("~/Temp"),lRandomFileName); 问题是服务器不是虚拟的,只能使用getter访问. 我得到了 “The method or operation is not implemented.” 我该如何模拟这台服务器? 我创建的测试如下
我的控制器中有以下行:
string lTempPath = Path.Combine(Server.MapPath("~/Temp"),lRandomFileName);

问题是服务器不是虚拟的,只能使用getter访问.

我得到了

“The method or operation is not implemented.”

我该如何模拟这台服务器?

我创建的测试如下:

[TestCase]
    public void PreviewActionShouldGenerateUrlOfPdf()
    {
        //Arrange
        var server = MockRepository.GenerateMock<HttpServerUtilityBase>();
        server.Stub(s => s.MapPath("~Temp")).Return("~/Temp");
        var httpContext = MockRepository.GenerateMock<HttpContextBase>();
        httpContext.Stub(hc => hc.Server).Return(server);
        httpContext.Server.Stub(s => s.MapPath("~/Temp")).Return("~/Temp");

        var controller = new StudiesController()
        {
            ReportingService = MockRepository.GenerateMock<IReportingService>(),SecurityService = MockRepository.GenerateMock<ISecurityService>()
        };


        controller.ControllerContext = new ControllerContext(httpContext,new RouteData(),controller);

        controller.ReportingService.Stub(rs => rs.GetStudyByGID(new Guid())).Return(new Study());
        controller.ReportingService.Stub(rs => rs.ListPractices()).Return(new[] { new Practice(),new Practice() });
        controller.SecurityService.Stub(ss => ss.GetUser("")).IgnoreArguments().Return(new User());

        controller.ControllerContext.HttpContext = MockRepository.GeneratePartialMock<FakeHttpContext>("http://test.com");
        controller.HttpContext.User = new FakePrincipal(new FakeIdentity("test"),new string[0]);
        controller.ControllerContext.HttpContext.Stub(x => x.Request).Return(MockRepository.GenerateMock<HttpRequestBase>());
        controller.ControllerContext.HttpContext.Request.Stub(x => x.Url).Return(new Uri("http://test.com"));



        controller.ReportingService.Stub(
            rs =>
            rs.GenerateReport(new Study(),new Practice(),new User(),false,ReportGenerationOutputFormat.PDF)).IgnoreArguments().Return(new StudyReportSnapshot());

        var content = new ContentResult();

        //Act

        var result = (ContentResult)controller.Preview(new Guid());

        //Assert
        Assert.AreEqual(result.Content,content.Content);

    }

解决方法

假设您正在使用某种IOC / DI容器,则不应依赖Controller.Server.相反,你应该使用HttpServerUtilityBase.

此示例假定Ninject为IOC容器,但任何常用容器都将执行以下操作:

首先,将HttpServerUtilityBase注册到您的IOC容器,如下所示:

kernel.Bind<HttpServerUtilityBase>().ToMethod(c => new HttpServerUtilityWrapper(HttpContext.Current.Server));

这将确保在运行时您的应用程序将使用当前请求的服务器属性.

然后,向控制器添加一个接受HttpServerUtilityBase实例的构造函数:

public MyController(HttpServerUtilityBase server)
{
    this._server = server;
}

现在,在您调用Server.MapPath之前的任何地方,只需调用_server.MapPath.

最后,在你的测试中,你可以像这样模拟HttpServerUtilityBase(假设Moq是模拟框架):

var server = new Mock<HttpServerUtilityBase>();
server.Setup(s => s.MapPath(It.IsAny<string>())).Returns<string>(s => /* set up how you want MapPath to behave here */);

编辑

既然你提到你没有使用DI框架,你可以诉诸“穷人的依赖注入”.基本上添加一个重载的构造函数:

public MyController()
    : this(new HttpServerUtilityWrapper(HttpContext.Current.Server))
{
}

public MyController(HttpServerUtilityBase server)
{
    this._server = server;
}

这将允许生产代码使用当前的Web请求,但是您可以创建自己的HttpServerUtilityBase实现以用于测试.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读