我正在尝试测试从Request.InputStream读取JSON并输出动态的控制器操作。我不明白Mock Request.InputStream类型应该是什么。我已经尝试过它作为一个MemoryStream并传递给它一个字节数组,但它无法读取它。
到目前为止,我的模拟看起来像这样:
var str = "{ MediaItem: null, ParentId: 2897, Post: null, PostContent: hello }";
byte[] bytes = new byte[str.Length * sizeof(char)];
Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
var stream = new MemoryStream(bytes);
var request = new Mock<HttpRequestBase>();
request.SetupGet(x => x.InputStream).Returns(stream);
request.Setup(x => x.InputStream).Returns(stream);
request.Setup(x => x.Url).Returns(new Uri("http://localhost:35199/api/comment/create"));
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
CommentController controller = new CommentController(pr, ur, er, apr, ar);
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
ActionResult expected = null;
ActionResult actual = controller.Create();
JSON阅读器执行此操作:
public static dynamic SqueezeJson(HttpRequestBase Request)
{
var bodyText = "";
using (var stream = Request.InputStream)
{
stream.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(stream))
bodyText = reader.ReadToEnd();
}
if (string.IsNullOrEmpty(bodyText)) return null;
return JsonConvert.DeserializeObject<ExpandoObject>(bodyText, new ExpandoObjectConverter());
}
这会抛出此错误:
解析属性名称后的字符无效。期待':'但得到了:a。路径'',第1行,第6位。
编辑:我应该提到我没有重构控制器代码的自由。
答案 0 :(得分:0)
看起来你的控制器做了太多工作。尝试在另一个类中抽象json reader,并将其注入控制器中。这样你将有2个独立的测试 - 一个用于读者本身,另一个用于控制器,它只是调用读者,而不是实际上不得不考虑读者如何工作。
像这样(伪代码):
public interface IJsonReader
{
dynamic SqueezeJson(Stream stream);
}
public class JsonReader : IJsonReader
{
//implement SqeezeJson method
}
public class MyController
{
private readonly IJsonReader _jsonReader;
public MyController(IJsonReader jsonReader)
{
_jsonReader = jsonReader;
}
public ActionResult Create()
{
var data = _jsonReader.SqeezeJson(Context.Request.InputStream);
//... do wahtever needed
}
}
// ... and the tests
[Test]
public void SqueezeJsonTest()
{
//test that the reader works as expected
}
public void ControllerTest()
{
//arrange
var requestStream = Mock.Of<Stream>();
var request = Mock.Of<HttpRequestBase>( r =>
r.InputStream == requestStream &&
r.Url == "http://whatever");
var context = Mock.Of<HttpRequestBase>(c=>c.Request == request);
dynamic sqeezedData = new ExpandoObject(); // populate with the expected data from reader
var mockReader = new Mock<IJsonReader>();
mockReader.Setup(r=>r.SqeezeJson(requestStream)).Returns(sqeezedData);
var controller = new MyController();
controller.Context = context;
//act
var result = controller.Create();
//assert
//whatever is needed to verify that the controller processed the sueezed data
}
答案 1 :(得分:0)
只是将您的Json字符串粘贴到解析器中,但它失败了。您是否尝试将其更改为有效的Json表示?
{ "MediaItem": "null", "ParentId": "2897", "Post": "null", "PostContent": "hello" }
针对您的方案进行了更新:
var str = "{ \"MediaItem\": \"null\",\"ParentId\": \"2897\", \"Post\": \"null\", \"PostContent\": \"hello\" }";
HTH