我想编写一个单元测试来测试一个名为UploadedFile的类的功能.
我面临的问题是这个类的静态构造函数使用HttpContext.Current属性,因为我从类库运行我的单元测试,我在测试时没有HttpContext.
看看我的静态构造函数:
static UploadedFile() { if (HttpContext.Current == null) throw new Exception("web server not available"); HttpServerUtility server = HttpContext.Current.Server; // SET UploadedFileMappingFile Names: _resourceFileNames = new StringDictionary(); _resourceFileNames[_suppoertedFileStructures] = server.MapPath(SupportedUploadedFileStructures); _resourceFileNames[_supportedFileStructuresXSD] = server.MapPath(SupportedUploadedFileStructuresXSD); _resourceFileNames[UploadedFileEnum.UploadedFileFormatENUM.CSV.ToString()] = server.MapPath(UploadedFileColumnMap); }
我应该在我的测试环境中做什么,以便HttpContext.Current不会为null,我可以成功设置它:
HttpServerUtility server = HttpContext.Current.Server;
解决方法
你不应该在你的函数中直接使用HttpContext.Current,因为你几乎不可能进行单元测试,正如你已经发现的那样.我建议你改用
HttpContextBase,它可以在你的类的构造函数中传递,也可以作为你正在测试的方法的参数传递.这将允许此类的消费者传递真正的
HttpContextWrapper,并且在您的单元测试中,您可以模拟您需要的方法.
var wrapper = new HttpContextWrapper(HttpContext.Current); Foo.UploadedFile(wrapper);
在您的单元测试中(使用Rhino Mocks):
var contextMock = MockRepository.GenerateMock<HttpContextBase>(); // TODO: Define expectations on the mocked object Foo.UploadedFile(contextMock);
或者,如果您愿意,请使用Constructor Injection.