我有以下 NancyFX 单元测试。我使用Shouldly断言库来提供一组扩展方法.Should---
[Fact]
public void Assessment__Should_return_assessment_state_for_specified_user()
{
const AssessmentState assessmentState = AssessmentState.Passed;
var user = Fake.Mentor();
using (var db = Fake.Db())
{
db.Save(user);
Fake.Assessment(user.Id, db, assessmentState);
db.ClearStaleIndexes();
}
var response = Fake.Browser(user.UserName, user.Password)
.Get("/assessment/state/" + user.Id, with => with.HttpRequest());
//var result = (dynamic)body.DeserializeJson<ExpandoObject>();
var result = (dynamic) JsonConvert.DeserializeObject<ExpandoObject>(response.Body.AsString());
result.ShouldNotBe(null);
((AssessmentState) result.State).ShouldBe(assessmentState);
}
此测试调用AssessmentService
定义为的 uri,它返回一个简单的 JSON 对象定义,该对象定义具有类型 (enum)/assessment/state/" + user.Id
的单个属性,要么,要么。State
AssessmentState
Passed
Failed
NotStarted
这是服务处理程序,因此您可以看到没有任何技巧。
Get["/assessment/state/{userid}"] = parameters =>
{
var assessment = AssessmentService.GetByUserId(Db, (string)parameters.userid);
return assessment == null ? HttpStatusCode.NotFound : Response.AsJson(new
{
assessment.State
});
};
这是此服务调用返回的 JSON 示例:
{"State":1}
一切正常,直到我尝试反序列化假 Nancy 浏览器返回的 JSON。BrowserResponse.Body
首先,我尝试使用 Nancy对象提供的内置方法:
var result = (dynamic)response.Body.DeserializeJson<ExpandoObject>();
这将反序列化为一个空对象。这不好。但是,如果我们使用 Newtonsoft 等价物,那么一切都很好(几乎)。
var result = (dynamic) JsonConvert.DeserializeObject<ExpandoObject>(response.Body.AsString());
JSON 反序列化现在可以工作,因此以下应该断言通过了出色的结果:
((AssessmentState) result.State).ShouldBe(assessmentState);
但是,由于我怀疑与匿名类型有关的原因,以下行在运行时失败(它编译得很好)。
result.ShouldNotBe(null);
这是相当多的信息。让我把它提炼成两个问题:
鉴于 Newtonsoft 版本可以,为什么 Nancy 内置的 JSON 反序列化器不起作用?
如何使用 JSON 反序列化生成的动态类型,以便应该扩展方法不会导致运行时异常?
谢谢