asp.net mvc - usar - Cómo realizar pruebas de unidad de JsonResult y colecciones en MSTest
unit test web api controller (6)
Soy muy nuevo en las pruebas unitarias, aunque he estado programando durante mucho tiempo. Quiero hacer de esto una parte de mi forma de desarrollo. Me encuentro con bloques sobre cómo hacer pruebas unitarias de cosas como una colección. Generalmente tengo mi script jQuery llamando a los métodos del lado del Servidor ASP.Net para obtener datos y rellenar tablas y similares. Parecen
Get_*Noun*()
que generalmente devuelve un JsonResult. ¿Alguna idea sobre qué y cómo probarlos usando las pruebas unitarias usando MSTest?
(Estoy usando la sintaxis de NUnit, pero MSUnit no debería estar muy lejos)
Podrías probar tu JsonResult así:
var json = Get_JsonResult()
dynamic data = json.Data;
Assert.AreEqual("value", data.MyValue)
Luego, en el proyecto que contiene el código a probar, edite el archivo AssemblyInfo.cs para permitir que el ensamblaje de prueba acceda al tipo anónimo:
[assembly: InternalsVisibleTo("Tests")]
Esto es para que la dinámica pueda determinar el tipo de objeto anónimo que se devuelve desde el valor json.Data;
Debería poder probar esto como cualquier otra cosa, siempre que pueda extraer los valores de JsonResult. Aquí hay un ayudante que hará eso por ti:
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);
}
Luego llame a su controlador como de costumbre y pruebe el resultado usando ese ayudante.
var jsonResult = yourController.YourAction(params);
bool testValue = GetValueFromJsonResult<bool>(jsonResult, "PropertyName");
Assert.IsFalse(testValue);
Mi sugerencia sería crear un modelo para los datos devueltos y luego convertir el resultado en ese modelo. De esa manera puedes verificar:
- la estructura es correcta
Los datos dentro del modelo son correctos.
// 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());
Podrías usar PrivateObject para hacer esto.
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());
Utiliza una reflexión similar a la respuesta de David Ruttka, pero le ahorrará algunos golpes de tecla.
Consulte http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.privateobject.aspx para obtener más información.
This es el mejor blog que he encontrado sobre este tema.
Mi favorito fue el 4º enfoque utilizando dinámicas. Tenga en cuenta que es necesario que se asegure de que las [assembly:InternalsVisibleTo("TestProject")]
internas sean visibles para su proyecto de prueba utilizando [assembly:InternalsVisibleTo("TestProject")]
que creo que es una buena idea en general.
[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);
}
Aquí hay una pequeña extensión para convertir fácilmente un Json ActionResult en el objeto que representa.
using System.Web.Mvc;
public static class WebExtensions
{
public static T ToJson<T>(this ActionResult actionResult)
{
var jsonResult = (JsonResult)actionResult;
return (T)jsonResult.Data;
}
}
Con esto, tu ''acto'' en la prueba se vuelve más pequeño:
var myModel = myController.Action().ToJson<MyViewModel>();