2

次の 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);
}

このテストは、 として定義されたAssessmentServiceuri を呼び出します。これは、タイプ (enum) 、または のいずれかの単一のプロパティを持つ単純な/assessment/state/" + user.IdJSON オブジェクト定義を返します。StateAssessmentStatePassedFailedNotStarted

ここにサービス ハンドラーがあるので、トリックがないことがわかります。

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最初に、ナンシーのオブジェクトが提供する組み込みメソッドを使用しようとしました。

var result = (dynamic)response.Body.DeserializeJson<ExpandoObject>();

これにより、空のオブジェクトに逆シリアル化されます。これは良くありません。ただし、同等の Newtonsoft を使用すれば、すべて問題ありません (ほぼ)。

var result = (dynamic) JsonConvert.DeserializeObject<ExpandoObject>(response.Body.AsString());

JSON デシリアライゼーションが機能するようになったため、次の Shouldly アサーションは見事にパスします。

((AssessmentState) result.State).ShouldBe(assessmentState);

ただし、匿名型に関係していると思われる理由により、次の行は実行時に失敗します (正常にコンパイルされます)。

result.ShouldNotBe(null);

当然の例外

それはかなり多くの情報です。それを 2 つの質問に要約させてください。

  1. Newtonsoft バージョンでは機能するのに、Nancy のビルトイン JSON デシリアライザーが機能しないのはなぜですか?

  2. Shouldly 拡張メソッドが実行時例外を引き起こさないように、JSON デシリアライゼーションによって生成された動的型をどのように操作すればよいですか?

ありがとう

4

1 に答える 1

4

最初の質問に答えることはできませんが、WRTのShouldlyおよび動的タイプであるShouldlyのShouldNotBeメソッドはの拡張メソッドobjectです。DLRでは、次のように入力されたオブジェクトに対して拡張メソッドを呼び出すことはできませんdynamic(したがって、表示されているランタイムバインダー例外)

結果に対してShouldNotBe(null)を呼び出したい場合は、object最初にキャストする必要があることをお勧めします(つまり、 ((object)result).ShouldNotBe(null):)

-バツ

于 2012-05-12T10:39:47.637 に答える