Каков наилучший способ модульного тестирования простого JsonResult? - PullRequest
0 голосов
/ 10 ноября 2011

В случае успешного вызова AJAX я хочу вернуть простой объект с Success = true

public ActionResult Foo(int id)
{
    // ...
    return Json(new {Success=true});
}

Это прекрасно работает, и объект, который получает мой javascript, выглядит как

{ Success : true }  

но поскольку возвращаемый объект является анонимным типом, я не могу сделать (что-то вроде) следующее в моем тесте:

var result = (JsonResult)controller.AddNote(id, message);
dynamic data = result.Data;

// Assert
Assert.That(data.Success, Is.EqualTo(true));

Поэтому я попытался вернуть ExpandoObject, который позволяет тесту работать так, как я хочу, но JSON, отправленный обратно в ответе AJAX, представляет собой беспорядок, , как подробно описано в этом вопросе .

[{"Key":"Success","Value":true}]

Есть ли простой, чистый способ добиться того, что кажется простым, или это единственный способ реализовать некоторую настраиваемую сериализацию, как в связанном вопросе?

Ответы [ 2 ]

1 голос
/ 10 ноября 2011
  1. Получить значение с помощью dynamic может работать, если вы пометите свой контроллер в сборе с помощью [assembly: InternalsVisibleTo("TestsProject")]. Поскольку классы, созданные для анонимных типов, являются внутренними, а привязка во время выполнения не работает с внутренними типами. В этой статье вы можете найти больше информации об этом.
  2. Если вам не нравится этот подход, вы можете вернуться к простому старому отражению (скрытому за некоторыми вспомогательными методами):

    [TestMethod]
    public void AddNote1()
    {
        ...
        var result = ((JsonResult)controller.AddNote(id, message));
        var data = result.Data;
    
        // Assert
        Assert.AreEqual(Get<bool>(data, "Success"), true);
     }
    
     private T Get<T>(object instance, string propertyName)
     {
         return (T) instance.GetType().GetProperty(propertyName).GetValue(instance, null);
     }
    
  3. Используйте именованные классы вместо анонимных.

  4. Вы должны использовать какой-то обходной путь сериализации, как вы упомянули.

0 голосов
/ 10 ноября 2011

Что вы можете сделать:

var js = new JavaScriptSerializer();
var response = new { id = 0, Status = false };
dynamic object = js.Deserialize(new StringReader(JSONText), response.GetType());

Assert.IsTrue(object.Success)

Что это значит:

  1. Создать JavaScriptSerializer.
  2. Создать новый анонимный объект с тем жемакет как ваш json, так что сериализатор знает, как выглядит ваш объект
  3. Десериализуйте json в новый динамический объект.

Недостатком этого является то, что у вас не будет IntelliSense наваш json-объект, поэтому компилятор не поймет любую орфографическую ошибку.

Примечание. Я написал код здесь в stackoverflow, поэтому в нем могут быть незначительные ошибки.Я не проверял, но это должно работать: P

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...