Comment tester L'Unité JsonResult et Collections dans MSTest
Je suis très nouveau dans les tests unitaires même si je code depuis très longtemps. Je veux en faire une partie de ma façon de développement. Je rencontre des blocs sur la façon de tester des choses comme une collection. J'ai généralement mon script jQuery appelant ASP.Net méthodes Côté Serveur pour obtenir des données et remplir des tables et autres. Ils ressemblent à
Get_*Noun*()
Qui renvoie généralement un JsonResult. Des idées sur quoi et comment les tester en utilisant des tests unitaires en utilisant MSTest?
6 réponses
Vous devriez être capable de tester cela comme toute autre chose, à condition de pouvoir extraire les valeurs de JsonResult. Voici une aide qui le fera pour vous:
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);
}
Appelez ensuite votre contrôleur comme d'habitude, et testez le résultat en utilisant cet assistant.
var jsonResult = yourController.YourAction(params);
bool testValue = GetValueFromJsonResult<bool>(jsonResult, "PropertyName");
Assert.IsFalse(testValue);
(j'utilise la syntaxe NUnit, mais MSUnit ne devrait pas être loin)
Vous pouvez tester votre JsonResult comme ceci:
var json = Get_JsonResult()
dynamic data = json.Data;
Assert.AreEqual("value", data.MyValue)
Ensuite, dans le projet qui contient le code à tester, éditez AssemblyInfo.fichier cs pour permettre à l'assembly de test d'accéder au type anonyme:
[assembly: InternalsVisibleTo("Tests")]
C'est ainsi que la dynamique peut déterminer le type d'objet anonyme renvoyé par le json.Valeur des données;
Ce est le meilleur blog que j'ai trouvé sur ce sujet.
Mon préféré était la 4ème approche utilisant la dynamique. Notez qu'il vous faut vous assurer que les internes sont visibles pour votre projet de test en utilisant [assembly:InternalsVisibleTo("TestProject")]
ce que je trouve être une idée raisonnablement bonne en général.
[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);
}
Vous pouvez utiliser PrivateObject pour le faire.
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());
Il utilise une réflexion similaire à la réponse de David Ruttka, mais cela vous fera économiser quelques touches.
Voir http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.privateobject.aspx pour plus d'informations.
Voici une petite extension pour convertir facilement un ActionResult JSON en l'objet qu'il représente.
using System.Web.Mvc;
public static class WebExtensions
{
public static T ToJson<T>(this ActionResult actionResult)
{
var jsonResult = (JsonResult)actionResult;
return (T)jsonResult.Data;
}
}
Avec cela, votre 'acte' dans le test devient plus petit:
var myModel = myController.Action().ToJson<MyViewModel>();
, Ma suggestion serait de créer un modèle pour les données renvoyées puis coulé le résultat dans ce modèle. De cette façon, vous pouvez vérifier:
- la structure est correcte
-
Les données dans le modèle sont correctes
// 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());