C# 单元测试MVC控制器-需要应用程序的路径
我继承了一个旧的ASP.net MVC应用程序,我试图反写单元测试,但遇到了一个错误。下面是我的单元测试:C# 单元测试MVC控制器-需要应用程序的路径,c#,asp.net-mvc,unit-testing,C#,Asp.net Mvc,Unit Testing,我继承了一个旧的ASP.net MVC应用程序,我试图反写单元测试,但遇到了一个错误。下面是我的单元测试: public void DashboardController_Index_ReturnsIndex() { var dashboardController = _mocker.Resolve<DashboardController>(); var controllerContextMock = new Mock<Contro
public void DashboardController_Index_ReturnsIndex()
{
var dashboardController = _mocker.Resolve<DashboardController>();
var controllerContextMock = new Mock<ControllerContext>();
var userMock = new Mock<IUserContext>();
userMock
.SetupGet(u => u.Identity.IsAuthenticated)
.Returns(true);
userMock
.Setup(u => u.Type)
.Returns(EUserType.Normal);
controllerContextMock
.SetupGet(c => c.HttpContext.User)
.Returns(userMock.Object);
controllerContextMock
.SetupGet(p => p.HttpContext.Request.Url)
.Returns(new Uri("http://localhost/Dashboard/Index"));
dashboardController.ControllerContext = controllerContextMock.Object;
var result = dashboardController.Index() as ViewResult;
Assert.Equal("Index", result.ViewName);
}
此方法的第三行出现异常,代码尝试将字符串拆分为字段。具体来说,这里有一个例外:
System.Web.HttpException(0x80004005):无法将应用程序相对虚拟路径“~/”设置为绝对路径,因为应用程序的路径未知
我已经看到它描述了如何在这个调用中注入一个假字符串,但是由于控制器本身并没有试图解析字符串,而是将它传递给另一个类中的一个helper方法,因此DI似乎不起作用。知道我如何在单元测试时伪造应用程序路径吗?在生产中,这段代码工作得很好。我想我可以重构控制器,将这个helper类用作依赖项,而不只是调用静态方法,但我希望找到一个不需要对生产代码进行代码更改的解决方案。不幸的是,正确的方法是,需要重构生产代码,以允许将helper方法作为依赖项注入。毕竟,创建单元测试以允许自信地重构代码不是一个优点吗?在这种情况下,生产代码不太容易进行回装单元测试(在尝试这样做时经常如此)
最好的方法是提升一个抽象级别,创建“行为测试”(如在行为驱动开发中),在更高级别上彻底检查控制器的行为,重构它以允许进行单元测试,如果行为没有改变,可以自信地进行重新拟合单元测试。有趣的问题,希望查看建议的路径/答案。
private static string GetResourceString(HttpContextBase httpContext, string sxExpression, string sxVirtualPath)
{
var context = new ExpressionBuilderContext(sxVirtualPath);
var builder = new ResourceExpressionBuilder();
var fields = (ResourceExpressionFields)builder.ParseExpression(sxExpression,
typeof(string), context);
if (string.IsNullOrEmpty(fields.ClassKey) == false)
return (string)httpContext.GetGlobalResourceObject(fields.ClassKey, fields.ResourceKey,
Thread.CurrentThread.CurrentCulture);
return (string)httpContext.GetLocalResourceObject(sxVirtualPath, fields.ResourceKey,
Thread.CurrentThread.CurrentCulture);
}