web-dev-qa-db-ja.com

MSTestでJsonResultとコレクションを単体テストする方法

私は非常に長い間コーディングを行ってきましたが、ユニットテストは非常に初めてです。これを自分の開発の一部にしたいと思っています。コレクションのようなものをユニットテストする方法についてブロックに遭遇します。私は通常、ASP.Netサーバー側のメソッドを呼び出してデータを取得したりテーブルにデータを入力したりするjQueryスクリプトを持っています。彼らはのように見えます

Get_*Noun*() 

これは通常、JsonResultを返します。 MSTestを使用した単体テストを使用してこれらをテストする方法と方法に関するアイデアはありますか?

26
mithun_daa

JsonResultから値を抽出できれば、他の方法と同じようにこれをテストできるはずです。これがあなたのためにそれをするヘルパーです:

private T GetValueFromJsonResult<T>(JsonResult jsonResult, string propertyName)
{
    var property =
        jsonResult.Data.GetType().GetProperties()
        .Where(p => string.Compare(p.Name, propertyName) == 0)
        .FirstOrDefault();

    if (null == property)
        throw new ArgumentException("propertyName not found", "propertyName");
    return (T)property.GetValue(jsonResult.Data, null);
}

次に、通常どおりコントローラーを呼び出し、そのヘルパーを使用して結果をテストします。

var jsonResult = yourController.YourAction(params);
bool testValue = GetValueFromJsonResult<bool>(jsonResult, "PropertyName");
Assert.IsFalse(testValue);
52
David Ruttka

(私はNUnit構文を使用していますが、MSUnitはそれほど遠くないはずです)

次のようにJsonResultをテストできます。

var json = Get_JsonResult()
dynamic data = json.Data;
Assert.AreEqual("value", data.MyValue)

次に、テストするコードを含むプロジェクトで、AssemblyInfo.csファイルを編集して、テストアセンブリが匿名タイプにアクセスできるようにします。

[Assembly: InternalsVisibleTo("Tests")]

これは、ダイナミックがjson.Data値から返される匿名オブジェクトのタイプを判別できるようにするためです。

20
Jafin

This は、このテーマに関して私が見つけた最高のブログです。

私のお気に入りは、ダイナミクスを使用した4番目のアプローチでした。 [Assembly:InternalsVisibleTo("TestProject")]を使用して、内部がテストプロジェクトに表示されることを確認する必要があることに注意してください。これは、一般的にはかなり良い考えです。

[TestMethod]     
public void IndexTestWithDynamic()     
{     
    //arrange     
    HomeController controller = new HomeController();     

    //act     
    var result = controller.Index() as JsonResult;     

    //assert     
    dynamic data = result.Data;  

    Assert.AreEqual(3, data.Count);     
    Assert.IsTrue(data.Success);     
    Assert.AreEqual("Adam", data.People[0].Name);     
}
3
Zaid Masud

PrivateObjectを使用してこれを行うことができます。

var jsonResult = yourController.YourAction(params);
var success = (bool)(new PrivateObject(jsonResult.Data, "success")).Target;
Assert.IsTrue(success);

var errors = (IEnumerable<string>)(new PrivateObject(jsonResult.Data, "errors")).Target;
Assert.IsTrue(!errors.Any());

David Ruttkaの答えと同様のリフレクションを使用しますが、いくつかのキーストロークを節約できます。

詳細については、 http://msdn.Microsoft.com/en-us/library/Microsoft.visualstudio.testtools.unittesting.privateobject.aspx を参照してください。

2
Rich Czyzewski

ここに小さな拡張機能があります JsonActionResultをそれが表すオブジェクトに簡単に変換します。

using System.Web.Mvc;

public static class WebExtensions
{
     public static T ToJson<T>(this ActionResult actionResult)
     {
         var jsonResult = (JsonResult)actionResult;

         return (T)jsonResult.Data;
     }
}

これにより、テストでの「行為」は小さくなります。

var myModel = myController.Action().ToJson<MyViewModel>();
0
Juanjo

私の提案は、返されたデータのモデルを作成し、その結果をそのモデルにキャストすることです。そうすれば、次のことを確認できます。

  1. 構造は正しい
  2. モデル内のデータは正しい

    // Assert
    var result = action
        .AssertResultIs<JsonResult>();
    
    var model = (UIDSearchResults)result.Data;
    Assert.IsTrue(model.IsValid);
    Assert.AreEqual("ABC", model.UIDType);
    Assert.IsNull(model.CodeID);
    Assert.AreEqual(4, model.PossibleCodes.Count());
    
0
jhilden