Как выполнить модульное тестирование JsonResult и коллекций в MSTest - PullRequest
26 голосов
/ 30 ноября 2011

Я очень новичок в модульном тестировании, хотя я уже очень давно программирую.Я хочу сделать это частью моего пути развития.Я сталкиваюсь с блоками о том, как проводить модульное тестирование таких вещей как коллекцияУ меня обычно есть скрипт jQuery, вызывающий методы на стороне сервера ASP.Net для получения данных и заполнения таблиц и тому подобное.Они выглядят как

Get_*Noun*() 

, что обычно возвращает JsonResult.Любые идеи о том, что и как проверить их с помощью модульных тестов с использованием MSTest?

Ответы [ 6 ]

52 голосов
/ 08 декабря 2011

Вы должны иметь возможность проверить это, как и все остальное, при условии, что вы можете извлечь значения из 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);
19 голосов
/ 20 марта 2012

(я использую синтаксис NUnit, но MSUnit не должен быть далеко)

Вы можете проверить свой JsonResult следующим образом:

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

Затем в проекте, который содержит коддля тестирования отредактируйте файл AssemblyInfo.cs, чтобы разрешить тестовой сборке доступ к анонимному типу:

[assembly: InternalsVisibleTo("Tests")]

Это позволяет динамическому устройству определять тип анонимного объекта, возвращаемого из значения json.Data;

3 голосов
/ 28 августа 2012

Этот - лучший блог, который я нашел на эту тему.

Моим любимым был 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);     
}
2 голосов
/ 17 мая 2012

Вы можете использовать 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 для получения дополнительной информации.

0 голосов
/ 25 апреля 2013

Я бы предложил создать модель для возвращаемых данных и затем привести результат в эту модель.Таким образом, вы можете проверить:

  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 голосов
/ 17 декабря 2012

Вот небольшое расширение для простого преобразования 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>();
...