提问人:geoff swartz 提问时间:11/16/2023 更新时间:11/16/2023 访问量:16
如何在 ASP.Net Core 中正确设置模拟 Request.Form
How to properly set up mock Request.Form in ASP.Net Core
问:
我正在尝试创建一个 HttpContextAccessor 模拟类以用于我的控制器单元测试。到目前为止,我有这个。
public class MockHttpContextAccessor
{
public Mock<IHttpContextAccessor> ContextAccessor { get; private set; }
public FormCollection RequestForm { get; private set; }
private FormFileCollection fileCollection;
public MockHttpContextAccessor()
{
var requestFeature = new HttpRequestFeature();
var features = new FeatureCollection();
features.Set<IHttpRequestFeature>(requestFeature);
ContextAccessor = new Mock<IHttpContextAccessor>();
var session = new MockHttpSession();
var context = new DefaultHttpContext(features);
fileCollection = new FormFileCollection();
RequestForm = new FormCollection(new Dictionary<string, StringValues>(), fileCollection);
ContextAccessor.Setup(x => x.HttpContext).Returns(context);
ContextAccessor.Setup(x => x.HttpContext.Session).Returns(session);
ContextAccessor.Setup(x => x.HttpContext.Request.Path).Returns("/path");
ContextAccessor.Setup(x => x.HttpContext.Request.Form).Returns(RequestForm);
ContextAccessor.Setup(x => x.HttpContext.Request.Form.Files).Returns(RequestForm.Files);
ContextAccessor.Setup(x => x.HttpContext.Request.Headers).Returns(new Mock<IHeaderDictionary>().Object);
}
public void AddFormFieldsOrFile(Dictionary<string, StringValues> fields, List<IFormFile> files = null)
{
if (files != null && files.Any())
{
ContextAccessor.Object.HttpContext.Request.Headers.Add("Content-Type", "multipart/form-data");
fileCollection.AddRange(files);
}
RequestForm = new FormCollection(fields, fileCollection);
}
}
public class MockHttpSession : ISession
{
Dictionary<string, object> sessionStorage = new Dictionary<string, object>();
public object this[string name]
{
get { return sessionStorage[name]; }
set { sessionStorage[name] = value; }
}
string ISession.Id
{
get
{
throw new NotImplementedException();
}
}
bool ISession.IsAvailable
{
get
{
throw new NotImplementedException();
}
}
IEnumerable<string> ISession.Keys
{
get { return sessionStorage.Keys; }
}
void ISession.Clear()
{
sessionStorage.Clear();
}
void ISession.Remove(string key)
{
sessionStorage.Remove(key);
}
void ISession.Set(string key, byte[] value)
{
sessionStorage[key] = value;
}
public Task LoadAsync(CancellationToken cancellationToken = new CancellationToken())
{
throw new NotImplementedException();
}
public Task CommitAsync(CancellationToken cancellationToken = new CancellationToken())
{
throw new NotImplementedException();
}
bool ISession.TryGetValue(string key, out byte[] value)
{
object storageValue = null;
if(sessionStorage.TryGetValue(key, out storageValue))
{
var bytes = storageValue as byte[];
if(bytes != null)
{
value = bytes;
return true;
}
value = Encoding.UTF8.GetBytes(storageValue.ToString());
return true;
}
value = null;
return false;
}
}
其中大部分工作正常。但是,如果我尝试访问 Request.Form 的值,则其上的 Keys 属性为 null,但是,Files 属性设置正确并且有一个文件。在我的测试设置中,这是我调用的用于设置表单值和文件的代码。
var content = "This is a test file";
var fileName = "test.pdf";
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(content);
writer.Flush();
stream.Position = 0;
IFormFile file = new FormFile(stream, 0, stream.Length, "field_id", fileName);
var formContents = new Dictionary<string, StringValues>()
{
{"attachment-id", "1"},
{"prelim", "false"}
};
_httpContextAccessor.AddFormFieldsOrFile(formContents, new List<IFormFile>{ file });
答: 暂无答案
评论