我有以下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
的{{1}} uri,它返回一个简单的JSON对象定义,该定义具有类型(枚举)/assessment/state/" + user.Id
的单个属性State
,{ {1}},AssessmentState
或Passed
。
这是服务处理程序,因此您可以看到没有技巧。
Failed
以下是此服务调用返回的JSON示例:
NotStarted
一切正常,直到我尝试反序列化假冒Nancy浏览器返回的JSON。首先,我尝试使用Nancy的Get["/assessment/state/{userid}"] = parameters =>
{
var assessment = AssessmentService.GetByUserId(Db, (string)parameters.userid);
return assessment == null ? HttpStatusCode.NotFound : Response.AsJson(new
{
assessment.State
});
};
对象提供的内置方法:
{"State":1}
这反序列化为一个空对象。哪个不好。但是,如果我们使用Newtonsoft等价物,那么一切都很好(几乎)。
BrowserResponse.Body
JSON反序列化现在可以正常工作,因此以下的应该断言通过了绚丽的颜色:
var result = (dynamic)response.Body.DeserializeJson<ExpandoObject>();
但是,由于我怀疑与匿名类型有关的原因,以下行在运行时失败(编译正常)。
var result = (dynamic) JsonConvert.DeserializeObject<ExpandoObject>(response.Body.AsString());
这是很多信息。让我把它归结为两个问题:
为什么Nancy的内置JSON反序列化器不能用于Newtonsoft版本呢?
如何使用JSON反序列化生成的动态类型,以便应用扩展方法不会导致运行时异常?
由于
答案 0 :(得分:4)
我无法回答第一个问题,但WRT应该是动态类型,应该ShouldNotBe
方法是object
上的扩展方法。 DLR不允许您对键入为dynamic
的对象调用扩展方法(因此您将看到的运行时绑定异常)
我建议如果你想在结果上调用ShouldNotBe(null),你必须先将它转换为object
(即:((object)result).ShouldNotBe(null)
)
-x