Подтвердить что ты не робот

Как Unit Test JsonResult и коллекции в MSTest

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

Get_*Noun*() 

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

4b9b3361

Ответ 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());