Как Unit Test JsonResult и коллекции в MSTest
Я очень новичок в модульном тестировании, даже несмотря на то, что кодирование очень долгое время. Я хочу сделать это частью моего пути развития. Я сталкиваюсь с блоками о том, как unit test вещи, подобные коллекции. Обычно у меня есть jQuery script, вызывающий методы ASP.Net Server для получения данных и заполнения таблиц и т.п. Они выглядят как
Get_*Noun*()
который обычно возвращает JsonResult. Любые идеи о том, что и как тестировать их с помощью модульных тестов с использованием MSTest?
Ответы
Ответ 1
Вы должны быть в состоянии проверить это, как и все остальное, при условии, что вы можете извлечь значения из 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);
Ответ 2
(Я использую синтаксис NUnit, но MSUnit не должен быть удален)
Вы можете проверить свой JsonResult следующим образом:
var json = Get_JsonResult()
dynamic data = json.Data;
Assert.AreEqual("value", data.MyValue)
Затем в проекте, который содержит тестируемый код, отредактируйте файл AssemblyInfo.cs, чтобы обеспечить доступ к ассемблеру тестовой сборки:
[assembly: InternalsVisibleTo("Tests")]
Это так, что динамик может определить тип анонимного объекта, возвращаемого из значения json.Data;
Ответ 3
Это - лучший блог, который я нашел на эту тему.
Моим любимым был 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);
}
Ответ 4
Вы можете использовать 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());
Он использует отражение, похожее на ответ Дэвида Руттки, однако он спасет вас несколькими нажатиями клавиш.
Подробнее см. http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.privateobject.aspx.
Ответ 5
Здесь небольшое расширение, чтобы легко преобразовать Json ActionResult в объект, который он представляет.
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>();
Ответ 6
Мое предложение состояло в том, чтобы создать модель для возвращаемых данных, а затем применить результат к этой модели. Таким образом, вы можете проверить:
- правильная структура
-
данные в модели правильны
// 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());