Z .
Z .

Reputation: 12837

how to unit test JsonResult that returns an array of anonymous objects?

I have an action that returns a json array of anonymous objects:

public JsonResult GetItems()
{
    var items = new[] { new { Id = 1, Name = "One" }, new { Id = 2, Name = "Two" } };
    return Json(items);
}

How do I write a test for that method? Something like this:

[TestMethod]
public void MyController_GetItems()
{
    var controller = new MyController();
    var result = controller.GetItems();
    dynamic items = result.Data;
    Assert.AreEqual("One", items[0].Name); // ???
}

Upvotes: 2

Views: 1032

Answers (2)

Fran
Fran

Reputation: 6520

How about something like this: JsonNetResult is a custom ActionResult that replaces the internal Microsoft Json serializer with JSON.net

using FakeItEasy;
using Newtonsoft.Json;
using NUnit.Framework;
using System;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

public class JsonNetResultFixture
{
    private JsonNetResult _sut;

    private Controller fakeController;
    private HttpContextBase fakeContext;
    private HttpRequestBase fakeRequest;
    private HttpResponseBase fakeResponse;
    private RequestContext fakeRequestContext;

    [SetUp]
    public void Setup()
    {
        fakeController = A.Fake<Controller>();
        fakeContext = A.Fake<HttpContextBase>();
        fakeRequest = A.Fake<HttpRequestBase>();
        fakeResponse = A.Fake<HttpResponseBase>();
        fakeRequestContext = new RequestContext(fakeContext, new RouteData());
        fakeController.ControllerContext = new ControllerContext(fakeRequestContext, fakeController);

        A.CallTo(() => fakeRequest.HttpMethod).Returns(HttpVerbs.Post.ToString());
        A.CallTo(() => fakeContext.Response).Returns(fakeResponse);
        A.CallTo(() => fakeContext.Request).Returns(fakeRequest);

        _sut = new JsonNetResult();
    }

    [Test]
    [ExpectedException(typeof(ArgumentNullException))]
    public void should_throw_argumentexception_if_context_is_null()
    {
        _sut.ExecuteResult(null);
    }

    [Test]
    public void should_write_serialized_class_to_output_stream()
    {
        //Arrange
        var sb = new StringBuilder();

        _sut.Data = new SerializableClass { Id = Guid.NewGuid(), Payload = "awesome payload" };

        var serializedData = JsonConvert.SerializeObject(_sut.Data, Formatting.Indented);

        A.CallTo(() => fakeResponse.Write(A<String>.Ignored)).Invokes((String x) => sb.Append(x));

        //Act
        _sut.ExecuteResult(fakeController.ControllerContext);

        //Assert
        Assert.That(sb.ToString(), Is.EqualTo(serializedData));
    }

    [Test]
    public void should_write_nothing_when_data_is_nothing()
    {
        //Arrange
        var sb = new StringBuilder();

        A.CallTo(() => fakeResponse.Write(A<String>.Ignored)).Invokes((String x) => sb.Append(x)).MustHaveHappened(Repeated.Never);

        //Act
        _sut.ExecuteResult(fakeController.ControllerContext);

        //Assert
        Assert.That(sb.ToString(), Is.EqualTo(String.Empty));
    }

    [Test]
    public void should_set_content_type_if_sent_in()
    {
        //Arrange
        var contentType = "text/xml";
        _sut.ContentType = contentType;

        //Act
        _sut.ExecuteResult(fakeController.ControllerContext);

        //Assert
        Assert.That(_sut.ContentType, Is.EqualTo(contentType));
    }

    [Test]
    public void should_set_content_encoding_if_sent_in()
    {
        //Arrange
        var contentEncoding = Encoding.BigEndianUnicode;
        _sut.ContentEncoding = contentEncoding;

        //Act
        _sut.ExecuteResult(fakeController.ControllerContext);

        //Assert
        Assert.That(_sut.ContentEncoding, Is.EqualTo(contentEncoding));
    }
}

public class SerializableClass
{
    public Guid Id { get; set; }
    public String Payload { get; set; }
}

Upvotes: 1

Z .
Z .

Reputation: 12837

var items = (dynamic[])result.Data;
Assert.AreEqual("One", items[0].Name);

Upvotes: 0

Related Questions