我有一个返回FileContentResult或NotModifiedResult的操作,它是一个自定义结果类型,它返回HTTP 304以指示所请求的资源尚未被修改,如下所示:
[ReplaceMissingPicture(Picture = "~/Content/Images/nothumbnail.png", MimeType = "image/png")]
public ActionResult Thumbnail(int id)
{
var item = Service.GetItem(id);
var requestTag = Request.Headers["If-None-Match"] ?? string.Empty;
var tag = Convert.ToBase64String(item.Version.ToArray());
if (tag == requestTag)
{
return new NotModifiedResult();
}
if (item.Thumbnail != null)
{
var thumbnail = item.Thumbnail.ToArray();
var mime = item.PictureMime;
Response.AppendHeader("ETag", tag);
return File(thumbnail, mime);
}
else
{
return null;
}
}
此操作需要访问Response对象,该对象在测试期间当然不存在,因此使此操作不可测试.我可以在它周围添加条件语句,以便它在测试期间运行,但是我无法测试正确设置的标头.
这个问题的解决方案是什么?
仅供参考,ReplaceMissingPicture过滤器返回一个特定的资源,以防从此操作返回null,以便出于同样的原因将MapPath()调用从控制器中移出.
最佳答案 第一步是创建一个简化所需服务的界面: –
public interface IHeaders
{
public string GetRequestHeader(string headerName);
public void AppendResponseHeader(string headerName, string headerValue);
}
现在创建一个默认实现: –
public Headers : IHeaders
{
public string GetRequestHeader(string headerName)
{
return HttpContext.Current.Request[headerName];
}
public void AppendResponseHeader(string headerName, string headerValue)
{
HttpContext.Current.Response.AppendHeader(headerName, headerValue);
}
}
现在为您的Controller添加一个新字段: –
private IHeaders myHeadersService;
向控制器添加新的构造函数: –
public MyController(IHeaders headersService)
{
myHeadersService = headersService;
}
修改或添加默认构造函数: –
public MyController()
{
myHeadersService = new Headers();
}
现在在您的Action代码中使用myHeadersService而不是Response和Request对象.
在您的测试中,创建您自己的IHeaders接口实现,以模拟/测试Action代码,并在构造Controller时传递该实现.