我有一些使用HostingEnvironment.MapPath
的代码,我想进行单元测试。
如何设置HostingEnvironment
以便在单元测试(mstest)项目中返回路径而不是null
?
答案 0 :(得分:16)
为什么你的ASP.NET MVC应用程序中有一个依赖于HostingEnvironment.MapPath的代码,你可以访问像HttpServerUtilityBase这样的对象来实现这个目标,并且可以很容易地进行模拟和单元测试?
让我们举个例子:一个控制器动作,它使用我们想要进行单元测试的抽象Server类:
public class HomeController : Controller
{
public ActionResult Index()
{
var file = Server.MapPath("~/App_Data/foo.txt");
return View((object)file);
}
}
现在,有很多方法可以对此控制器操作进行单元测试。我个人喜欢使用MVcContrib.TestHelper。
但是让我们看看如何使用开箱即用的模拟框架来实现这一目标。我在这个例子中使用Rhino Mocks:
[TestMethod]
public void Index_Action_Should_Calculate_And_Pass_The_Physical_Path_Of_Foo_As_View_Model()
{
// arrange
var sut = new HomeController();
var server = MockRepository.GeneratePartialMock<HttpServerUtilityBase>();
var context = MockRepository.GeneratePartialMock<HttpContextBase>();
context.Expect(x => x.Server).Return(server);
var expected = @"c:\work\App_Data\foo.txt";
server.Expect(x => x.MapPath("~/App_Data/foo.txt")).Return(expected);
var requestContext = new RequestContext(context, new RouteData());
sut.ControllerContext = new ControllerContext(requestContext, sut);
// act
var actual = sut.Index();
// assert
var viewResult = actual as ViewResult;
Assert.AreEqual(viewResult.Model, expected);
}
答案 1 :(得分:1)
我今天正在为我无法控制的代码编写测试,他们使用了
private static String GetApplicationPath()
{
return HostingEnvironment.ApplicationVirtualPath.TrimEnd('/');
}
所以这里有一个C#反射黑客来设置该值
var path = "/aaaa/bb";
HostingEnvironment hostingEnvironment;
if (HostingEnvironment.IsHosted.isFalse())
new HostingEnvironment();
hostingEnvironment = (HostingEnvironment)typeof(HostingEnvironment).fieldValue("_theHostingEnvironment");
var virtualPath = "System.Web".assembly()
.type("VirtualPath").ctor();
virtualPath.field("_virtualPath", path);
//return virtualPath.prop("VirtualPathString");
//return virtualPath.prop("VirtualPathStringNoTrailingSlash");
hostingEnvironment.field("_appVirtualPath", virtualPath);
//hostingEnvironment.field("_appVirtualPath") == virtualPath;
return HostingEnvironment.ApplicationVirtualPath == path;
//using System.Web.Hosting
答案 2 :(得分:0)
这取决于您使用的模拟或隔离框架。您可能希望查看a)围绕可以模拟的静态属性创建包装类型,或b)使用可以模拟静态属性的框架 - 例如Moles或Typemock Isolator
答案 3 :(得分:0)
由于遇到相同的问题,我更改了代码位。 来自
strhtmlTemplate = File.ReadAllText(System.Web.Hosting.HostingEnvironment.MapPath(Lgetfilepath.CVal));
收件人
strhtmlTemplate = File.ReadAllText(HttpContextFactory.Current.Server.MapPath(Lgetfilepath.CVal));
用于单元测试
public HttpContextBase mockHttpContextBase()
{
var moqContext = new Mock<HttpContextBase>();
var moqRequest = new Mock<HttpRequestBase>();
var moqServer = new Mock<HttpServerUtilityBase>();
var moqPath = new Mock<ConfigurationBase>();
moqContext.Setup(x => x.Request).Returns(moqRequest.Object);
moqContext.Setup(x => x.Server.MapPath(@"~\Data\xxxxxxx")).Returns(Environment.CurrentDirectory+@"\xxxxxx");
setupApplication(moqContext);
return moqContext.Object;
}
现在我们在编写TestClass时,需要引用上述方法进行模拟。希望它对您的测试案例有帮助。
MockDataUT mockData = new MockDataUT();
var mockRequestContext = new HttpRequestContext();
HttpContextFactory.SetCurrentContext(mockData.mockHttpContextBase());
答案 4 :(得分:-4)
只需使用此代码..
在根目录中创建一个新文件夹名称引用,并将您的文件添加到此文件夹中。
使用此
public static XElement GetFile()
{
HttpContext.Current = new HttpContext(new HttpRequest("", "http://www.google.com", ""), new HttpResponse(new StringWriter()));
var doc = new XmlDocument();
var file = HttpContext.Current.Server.MapPath("\\") + "abc.xml";
doc.Load(file);
var e = XElement.Load(new XmlNodeReader(doc));
return e;
}