匿名型を含むJsonResultのアサーション 質問する

匿名型を含むJsonResultのアサーション 質問する

私は、JsonResult を返すコントローラーの 1 つでメソッドを単体テストしようとしていました。驚いたことに、次のコードは機能しませんでした。

[HttpPost]
public JsonResult Test() {
    return Json(new {Id = 123});
}

これは私がテストする方法です (テスト コードは別のアセンブリに存在することにも注意してください)。

// Act
dynamic jsonResult = testController.Test().Data;

// Assert
Assert.AreEqual(123, jsonResult.Id);

例外がAssertスローされます:

「オブジェクト」には「ID」の定義が含まれていません

私はその後、次の方法でこの問題を解決しました。

[HttpPost]
public JsonResult Test() {
   dynamic data = new ExpandoObject();
   data.Id = 123;
   return Json(data);
}

最初のものがなぜ機能しないのかを理解しようとしています。また、匿名型以外であれば基本的にすべて機能しているようです。

ベストアンサー1

明確に言うと、あなたが遭遇している具体的な問題は、C# dynamic が非パブリック メンバーでは機能しないということです。これは設計によるもので、おそらくそのようなことを避けるためのものでしょう。LukLed が述べたように、匿名型は同じアセンブリ内でのみパブリックであるため (または、より正確には、匿名型はinternalではなく とマークされるだけなのでpublic)、この障壁にぶつかっています。

おそらく最もクリーンな解決策は、 を使用することですInternalsVisibleTo。これにより、非パブリック メンバーにアクセスできる別のアセンブリに名前を付けることができます。これをテストに使用することが、これが存在する主な理由の 1 つです。例では、プライマリ プロジェクトの AssemblyInfo.cs に次の行を配置します。

[assembly: InternalsVisibleTo("AssemblyNameOfYourTestProject")]

それを実行すると、エラーは解消されます (自分で試してみました)。

あるいは、ブルートフォースリフレクションを使用することもできます。

Assert.AreEqual(123, jsonResult.GetType().GetProperty("Id").GetValue(jsonResult, null));

おすすめ記事