Skip to content

Commit

Permalink
Add ability to deserialize to JSON using custom JsonSerializerSettings
Browse files Browse the repository at this point in the history
  • Loading branch information
basdijkstra committed Jun 19, 2023
1 parent abcc56d commit 2f9c866
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 8 deletions.
45 changes: 45 additions & 0 deletions RestAssured.Net.Tests/CustomJsonSerializerSettingsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace RestAssured.Tests
using Newtonsoft.Json;
using NUnit.Framework;
using RestAssured.Request.Builders;
using RestAssured.Tests.Models;
using WireMock.Matchers;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
Expand Down Expand Up @@ -94,6 +95,31 @@ public void CustomJsonSerializerSettingsCanBeSuppliedInRequestSpecification()
.StatusCode(201);
}

/// <summary>
/// A test demonstrating RestAssuredNet syntax for deserializing
/// a JSON response into an object using custom JsonSerializerSettings
/// when deserializing. With default settings, the exception would not be
/// thrown (MissingMemberHandling defaults to Ignore).
/// </summary>
[Test]
public void CustomJsonSerializerSettingsCanBeSuppliedWhenDeserializing()
{
this.CreateStubForObjectDeserializationWithCustomSettings();

JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Error;

Assert.Throws<JsonSerializationException>(() =>
{
Place place = (Place)Given()
.When()
.Get("http://localhost:9876/object-deserialization-custom-settings")
.Then()
.UsingJsonSerializerSettings(jsonSerializerSettings)
.DeserializeTo(typeof(Place));
});
}

/// <summary>
/// Creates the stub response for the object serialization example using custom JsonSerializerSettings.
/// </summary>
Expand All @@ -104,5 +130,24 @@ private void CreateStubForObjectSerializationWithCustomSettings()
.RespondWith(Response.Create()
.WithStatusCode(201));
}

/// <summary>
/// Creates the stub response for the object deserialization example using custom JsonSerializerSettings.
/// </summary>
private void CreateStubForObjectDeserializationWithCustomSettings()
{
var responseBody = new
{
Name = "Beverly Hills",
Inhabitants = 100000,
IsCapital = false,
State = "California",
};

this.Server?.Given(Request.Create().WithPath("/object-deserialization-custom-settings").UsingGet())
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBodyAsJson(responseBody));
}
}
}
3 changes: 1 addition & 2 deletions RestAssured.Net.Tests/ResponseBodyDeserializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ public void ObjectCanBeDeserializedFromJsonAfterVerifications()
.Then()
.StatusCode(200)
.And()
.Extract()
.As(typeof(Location));
.DeserializeTo(typeof(Location));

Assert.That(responseLocation.Country, Is.EqualTo("United States"));
Assert.That(responseLocation.Places?.Count, Is.EqualTo(2));
Expand Down
7 changes: 4 additions & 3 deletions RestAssured.Net/Response/Deserialization/Deserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ internal class Deserializer
/// </summary>
/// <param name="response">The <see cref="HttpResponseMessage"/> containing the body to be deserialized.</param>
/// <param name="type">The type to deserialize the response body into.</param>
/// /// <param name="deserializeAs">Indicates how to interpret the response content when deserializing.</param>
/// <param name="deserializeAs">Indicates how to interpret the response content when deserializing.</param>
/// <param name="jsonSerializerSettings">The <see cref="JsonSerializerSettings"/> to use when deserializing to JSON.</param>
/// <returns>The deserialized response body object.</returns>
/// <exception cref="DeserializationException">Thrown when deserialization of the response body fails.</exception>
internal static object DeserializeResponseInto(HttpResponseMessage response, Type type, DeserializeAs deserializeAs)
internal static object DeserializeResponseInto(HttpResponseMessage response, Type type, DeserializeAs deserializeAs, JsonSerializerSettings jsonSerializerSettings)
{
string responseBodyAsString = response.Content.ReadAsStringAsync().Result;

Expand Down Expand Up @@ -69,7 +70,7 @@ internal static object DeserializeResponseInto(HttpResponseMessage response, Typ

if (responseMediaType == null || responseMediaType.Contains("json"))
{
return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result, type) ?? string.Empty;
return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result, type, jsonSerializerSettings) ?? string.Empty;
}
else if (responseMediaType.Contains("xml"))
{
Expand Down
6 changes: 4 additions & 2 deletions RestAssured.Net/Response/ExtractableResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace RestAssured.Response
using System.Net.Http;
using System.Xml;
using HtmlAgilityPack;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestAssured.Response.Deserialization;
using RestAssured.Response.Exceptions;
Expand Down Expand Up @@ -181,7 +182,7 @@ public string Header(string name)
/// <param name="type">The object type to deserialize into.</param>
/// /// <param name="deserializeAs">Indicates how to interpret the response content when deserializing.</param>
/// <returns>The deserialized response object.</returns>
[Obsolete("Please use DeserializeTo() instead. This method will be removed in version 3.0.0.", false)]
[Obsolete("Please DeserializeTo() instead of Extract().As(). This method will be removed in version 3.0.0.", false)]
public object As(Type type, DeserializeAs deserializeAs = DeserializeAs.UseResponseContentTypeHeaderValue)
{
return this.DeserializeTo(type, deserializeAs);
Expand All @@ -193,9 +194,10 @@ public object As(Type type, DeserializeAs deserializeAs = DeserializeAs.UseRespo
/// <param name="type">The object type to deserialize into.</param>
/// /// <param name="deserializeAs">Indicates how to interpret the response content when deserializing.</param>
/// <returns>The deserialized response object.</returns>
[Obsolete("Please use DeserializeTo() instead of Extract().DeserializeTo(). This method will be removed in version 3.0.0.", false)]
public object DeserializeTo(Type type, DeserializeAs deserializeAs = DeserializeAs.UseResponseContentTypeHeaderValue)
{
return Deserializer.DeserializeResponseInto(this.response, type, deserializeAs);
return Deserializer.DeserializeResponseInto(this.response, type, deserializeAs, new JsonSerializerSettings());
}

/// <summary>
Expand Down
14 changes: 13 additions & 1 deletion RestAssured.Net/Response/VerifiableResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class VerifiableResponse
private readonly TimeSpan elapsedTime;

private bool logOnVerificationFailure = false;
private JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings();

/// <summary>
/// Initializes a new instance of the <see cref="VerifiableResponse"/> class.
Expand Down Expand Up @@ -628,6 +629,17 @@ public VerifiableResponse MatchesInlineDtd()
return this;
}

/// <summary>
/// Sets the <see cref="JsonSerializerSettings"/> to use when deserializing the response payload to JSON.
/// </summary>
/// <param name="jsonSerializerSettings">The <see cref="JsonSerializerSettings"/> to apply when deserializing.</param>
/// <returns>The current <see cref="VerifiableResponse"/> object.</returns>
public VerifiableResponse UsingJsonSerializerSettings(JsonSerializerSettings jsonSerializerSettings)
{
this.jsonSerializerSettings = jsonSerializerSettings;
return this;
}

/// <summary>
/// Deserializes the response content into the specified type and returns it.
/// </summary>
Expand All @@ -636,7 +648,7 @@ public VerifiableResponse MatchesInlineDtd()
/// <returns>The deserialized response object.</returns>
public object DeserializeTo(Type type, DeserializeAs deserializeAs = DeserializeAs.UseResponseContentTypeHeaderValue)
{
return Deserializer.DeserializeResponseInto(this.response, type, deserializeAs);
return Deserializer.DeserializeResponseInto(this.response, type, deserializeAs, this.jsonSerializerSettings);
}

/// <summary>
Expand Down

0 comments on commit 2f9c866

Please sign in to comment.