NancyFX:如何通过BrowserResponse.Body.DeserializeJson反序列化动态类型(单元测试)

时间:2012-05-07 12:14:25

标签: json unit-testing nancy

我有以下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}},AssessmentStatePassed

这是服务处理程序,因此您可以看到没有技巧。

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());

Shouldly Exception

这是很多信息。让我把它归结为两个问题:

  1. 为什么Nancy的内置JSON反序列化器不能用于Newtonsoft版本呢?

  2. 如何使用JSON反序列化生成的动态类型,以便应用扩展方法不会导致运行时异常?

  3. 由于

1 个答案:

答案 0 :(得分:4)

我无法回答第一个问题,但WRT应该是动态类型,应该ShouldNotBe方法是object上的扩展方法。 DLR不允许您对键入为dynamic的对象调用扩展方法(因此您将看到的运行时绑定异常)

我建议如果你想在结果上调用ShouldNotBe(null),你必须先将它转换为object(即:((object)result).ShouldNotBe(null)

-x