我正在为一个从Request.InputStream读取POST主体的WebApi控制器编写单元测试。我需要设置HttpContext.Current.Request.InputStream的inputstream属性,或者设置inputstream的内容。到目前为止,这是我的单元测试代码,但它不断抛出异常:
var originalStream = HttpContext.Current.Request.InputStream;
Stream newStream = new MemoryStream(ASCIIEncoding.Default.GetBytes("Test String"));
var propInfo = originalStream.GetType().GetProperty("CanWrite");
propInfo.SetValue(originalStream, true);
newStream.CopyTo(originalStream);
propInfo.SetValue(originalStream, false);
我在SetValue行上遇到以下异常:
ArgumentException: Property set method not found
我是否认为这一切都错了?我的控制器读取输入流并将其反序列化为JSON,因此我需要能够将数据插入到该流中。我只是不知道该怎么做。非常感谢。
答案 0 :(得分:2)
public abstract bool CanWrite { get; }
。该属性没有setter ..因此你的错误。
在您的示例中,originalStream
的类型为Stream
。将其包装在另一个流中以供测试。您没有测试HttpRequest.InputStream
,您正在测试反序列化...
var originalStream = new StreamReader(HttpContext.Current.Request.InputStream);
var content = originalStream.ReadToEnd();
..等等。
您甚至可以考虑完全使用请求输入,因为您并没有真正测试它。
编辑:
进一步扩展。您应该将其移出控制器操作..执行以下操作:
public class YourController : Controller {
private readonly IStreamWrapper _streamWrapper;
public YourController(IStreamWrapper wrapper) {
_streamWrapper = wrapper;
}
public ActionResult MethodYouAreTesting() {
var result = _streamWrapper.Process(HttpRequest.InputStream);
}
}
public class Tests {
public void YourTestMethod() {
var controller = new YourController(new FakeStreamWrapper()); // mock perhaps?
// Asserts here for the controller action
}
public void YourWrapperTester() {
var wrapper = new RealStreamWrapper();
// test Process method here..
}
}
然后您可以单独测试流读取和反序列化。
这是否有意义还是让它变得更复杂? :/
答案 1 :(得分:0)
InputStream是一个只读流。
有几种方法。从最简单的开始:
创建StreamReader的实例并在InputStream上调用ReadToEnd()以获取正在发送的数据。
获得内容后,您可以在进行JSON转换之前根据需要进行修改。
同样,这是做你想做的最简单,最不优雅的方式,但它应该有效。