单元测试控制器上下文的空引用异常

时间:2015-10-26 09:27:53

标签: c# unit-testing asp.net-web-api

我试图测试控制器,我想改变它的上下文,所以我可以在请求中发布带有文件的消息我的代码看起来像这样:

System.Drawing.Image image = System.Drawing.Image.FromFile("..\\..\\Images\\UploadFileTest.jpg");

var converter = new System.Drawing.ImageConverter();
byte[] byteContent = (byte[]) converter.ConvertTo(image,typeof(byte[]));
var content = new ByteArrayContent(byteContent);
content.Headers.Add("Content-Disposition", "form-data");
var controllerContext = new HttpControllerContext()
{
    Request = new HttpRequestMessage() { Content = new MultipartContent() { content } }
};
var controller = new ActionsController();
controller.ControllerContext = controllerContext;
string fileUrl = controller.UploadFile();

但是我在我的控制器上获得了NullReferenceExcetion:

var request = HttpContext.Current.Request;

3 个答案:

答案 0 :(得分:2)

在生产环境中,托管应用程序的IIS服务器会为每个请求填充HttpContext.Current。(特定上下文)

在您的UT中,没有任何内容填充HttpContext.Current到实例,这就是问题所在。

您必须初始化HttpContext.Current

HttpContext.Current = new HttpContext(new HttpRequest("", "http://blabla.com", ""),
                                      new HttpResponse(new StringWriter()));

还有一件事(以防你假装HttpContext); HttpContextsealed类,您无法使用Rhino-Mocks / Moq等代理工具伪造它。您必须使用代码编织工具,例如MsFakes / TypeMock Isolator ...

答案 1 :(得分:0)

我不确定您是否在Asp.net Mvc中使用此代码,但我会假设您是。我想到这样做的最好方法是在Request对象上编写一个扩展方法,然后在那个方法中做这样的魔术,

        public static class RequestMessageExtensions
    {
        internal static byte[] GetContent(this HttpRequestMessage request)
        {
            System.Drawing.Image image = System.Drawing.Image.FromFile("..\\..\\Images\\UploadFileTest.jpg");

        var converter = new System.Drawing.ImageConverter();
        byte[] byteContent = (byte[]) converter.ConvertTo(image,typeof(byte[]));
        var content = new ByteArrayContent(byteContent);
        content.Headers.Add("Content-Disposition", "form-data");

return content;
        }
  }

然后,您可以调用请求对象上的内容并访问您的数据。

我希望这会有所帮助

由于

答案 2 :(得分:0)

您可以使用Typemock Isolator伪造HttpContext:

var fake = Isolate.Fake.AllInstances<HttpContext>();
Isolate.Fake.StaticMethods<HttpContext>();

这些行产生所谓的递归伪造,这意味着调用任何成员及其成员等不会导致异常,它会返回默认值或其他递归伪造。此外,它解决了伪造HttpContext时通常会出现的单例问题。

如果要设置特定值,只需使用Isolate.WhenCalled(..)。Return()方法。例如:

Isolate.WhenCalled(() => HttpContext.Current.Request).WillReturn(new HttpRequest("", "http://smth.com", ""));

希望它能够结束!