Class HttpResponseMessageAssertions
- Namespace
- JsonAssertions.TUnit
- Assembly
- JsonAssertions.TUnit.dll
Fluent TUnit entry points that apply the JSON assertions directly to an
HttpResponseMessage: the response body is read as text and the assertion runs
against it, so a test can write await Assert.That(response).HasJsonProperty("user.name", ct)
without a separate read-and-parse step. This is the assertion family's first-class HTTP
entry point; reading an HTTP response body is the dominant way JSON reaches a test.
[SuppressMessage("Usage", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "These are [GenerateAssertion] source methods: the method name becomes the fluent chain entry point (Assert.That(response).HasJsonProperty(...)), so an Async suffix would corrupt the assertion surface.")]
[SuppressMessage("Performance", "MA0109:Consider adding an overload with a Span<T> or Memory<T>", Justification = "The one-of overloads take T[] so callers can use a C# 12 collection expression literal (HasJsonValueOneOf(\"status\", [\"Healthy\", \"Degraded\"])); a ReadOnlySpan<T> overload cannot be expressed under TUnit's [GenerateAssertion] source generator (ref struct parameters are unsupported), and assertion call sites do not need the allocation profile a Span overload would provide.")]
public static class HttpResponseMessageAssertions
- Inheritance
-
HttpResponseMessageAssertions
- Inherited Members
Remarks
Each method is generated into a TUnit assertion chain via the
[GenerateAssertion] source generator. The methods are asynchronous
(Task<TResult> of TUnit.Assertions.Core.AssertionResult) because reading the response
body is asynchronous; the body read flows the supplied
CancellationToken, which defaults to None.
A response body that is not valid JSON fails the assertion with an explained message (via JsonAssertions.TUnit.JsonStringSource) rather than throwing a raw JsonException. The body covers only the JSON payload; status-code assertions are intentionally out of scope (TUnit and HTTP-test libraries already cover those).
Methods
ContainsJson(HttpResponseMessage, string, Action<JsonEquivalenceOptions>?, CancellationToken)
Asserts the response body contains expectedSubset as a JSON
subset, with comparison options (ignored paths, order-insensitive arrays) set by
configure.
[GenerateAssertion]
public static Task<AssertionResult> ContainsJson(this HttpResponseMessage response, string expectedSubset, Action<JsonEquivalenceOptions>? configure, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
expectedSubsetstringThe expected subset document text.
configureAction<JsonEquivalenceOptions>A callback that sets comparison options. May be null for the defaults.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
ContainsJson(HttpResponseMessage, string, CancellationToken)
Asserts the response body contains expectedSubset as a JSON
subset: every property in the expected document must be present in the body with an
equivalent value (recursively), while the body may carry additional properties. The failure
lists every missing or mismatched field.
[GenerateAssertion]
public static Task<AssertionResult> ContainsJson(this HttpResponseMessage response, string expectedSubset, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
expectedSubsetstringThe expected subset document text.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
DoesNotHaveJsonProperty(HttpResponseMessage, string, CancellationToken)
Asserts the response body has no JSON property at the dot-separated
path.
[GenerateAssertion]
public static Task<AssertionResult> DoesNotHaveJsonProperty(this HttpResponseMessage response, string path, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
user.address.city.cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasEmptyJsonArray(HttpResponseMessage, string, CancellationToken)
Asserts the value at the dot-separated path in the response
body is a JSON array with no elements.
[GenerateAssertion]
public static Task<AssertionResult> HasEmptyJsonArray(this HttpResponseMessage response, string path, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
items.cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonArrayLength(HttpResponseMessage, string, int, CancellationToken)
Asserts the value at the dot-separated path in the response
body is a JSON array with exactly expectedLength elements.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonArrayLength(this HttpResponseMessage response, string path, int expectedLength, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
items.expectedLengthintThe expected array length.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonBoolean(HttpResponseMessage, string, CancellationToken)
[GenerateAssertion]
public static Task<AssertionResult> HasJsonBoolean(this HttpResponseMessage response, string path, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA path of dot-separated property names and zero-based bracket indices, for example
user.active.cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonProperty(HttpResponseMessage, string, CancellationToken)
Asserts the response body has a JSON property at the dot-separated
path.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonProperty(this HttpResponseMessage response, string path, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
user.address.city.cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonResponse<T>(HttpResponseMessage, HttpStatusCode, JsonTypeInfo<T>, T, CancellationToken)
Asserts the response has the expected HTTP status code AND the body
deserializes (via the supplied jsonTypeInfo) to a value structurally
equal to expected under Equals(object, object).
AOT-clean: the supplied JsonTypeInfo<T> is the source-generated entry for
T in the consumer's JsonSerializerContext; the assertion
uses no runtime reflection. Failure messages include the response body (truncated at
256 chars) so the diagnostic surfaces the structured-error shape for non-200 responses
and the actual JSON shape for deserialization failures.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonResponse<T>(this HttpResponseMessage response, HttpStatusCode expectedStatus, JsonTypeInfo<T> jsonTypeInfo, T expected, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response.
expectedStatusHttpStatusCodeThe expected HTTP status code.
jsonTypeInfoJsonTypeInfo<T>The JsonTypeInfo<T> for AOT-clean deserialization.
expectedTThe expected deserialized value (compared by Equals(object, object)).
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
A passed assertion when status and value both match; otherwise a failed assertion with a body-aware diagnostic message.
Type Parameters
TThe expected response-body type.
Exceptions
- ArgumentNullException
A required argument is null.
HasJsonValue(HttpResponseMessage, string, bool, CancellationToken)
Asserts the response body has the boolean value expected at
the dot-separated path.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValue(this HttpResponseMessage response, string path, bool expected, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
user.active.expectedboolThe expected boolean value.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValue(HttpResponseMessage, string, double, CancellationToken)
Asserts the response body has the numeric value expected at
the dot-separated path.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValue(this HttpResponseMessage response, string path, double expected, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
user.age.expecteddoubleThe expected numeric value.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValue(HttpResponseMessage, string, int, CancellationToken)
Asserts the response body has the 32-bit integer value expected
at the dot-separated path, matching whether the JSON encodes it as a number
or as a numeric string and comparing exactly. System.Text.Json writes int32 as a JSON
number while Protobuf's JsonFormatter can emit a JSON string; both are matched.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValue(this HttpResponseMessage response, string path, int expected, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
user.age.expectedintThe expected 32-bit integer value.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValue(HttpResponseMessage, string, long, CancellationToken)
Asserts the response body has the 64-bit integer value expected
at the dot-separated path, matching whether the JSON encodes it as a number
or as a numeric string (parsed with InvariantCulture) and
comparing exactly. Protobuf serializes int64 as a JSON string while System.Text.Json
writes it as a JSON number; both are matched.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValue(this HttpResponseMessage response, string path, long expected, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
guid.high.expectedlongThe expected 64-bit integer value.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValue(HttpResponseMessage, string, string, CancellationToken)
Asserts the response body has the string value expected at
the dot-separated path.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValue(this HttpResponseMessage response, string path, string expected, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
user.name.expectedstringThe expected string value.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValue(HttpResponseMessage, string, uint, CancellationToken)
Asserts the response body has the unsigned 32-bit integer value
expected at the dot-separated path, matching whether the
JSON encodes it as a number or as a numeric string and comparing exactly. System.Text.Json
writes uint32 as a JSON number while Protobuf's JsonFormatter can emit a JSON
string; both are matched.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValue(this HttpResponseMessage response, string path, uint expected, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
user.age.expecteduintThe expected unsigned 32-bit integer value.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValue(HttpResponseMessage, string, ulong, CancellationToken)
Asserts the response body has the unsigned 64-bit integer value
expected at the dot-separated path, matching whether the
JSON encodes it as a number or as a numeric string (parsed with
InvariantCulture) and comparing exactly. Protobuf serializes
uint64 as a JSON string while System.Text.Json writes it as a JSON number; both are
matched.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValue(this HttpResponseMessage response, string path, ulong expected, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
guid.low.expectedulongThe expected unsigned 64-bit integer value.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValueKind(HttpResponseMessage, string, JsonValueKind, CancellationToken)
Asserts the value at the dot-separated path in the response
body is of the given JsonValueKind.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValueKind(this HttpResponseMessage response, string path, JsonValueKind expectedKind, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
data.expectedKindJsonValueKindThe expected JSON value kind.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValueMatching(HttpResponseMessage, string, Func<JsonElement, bool>, CancellationToken)
Asserts the value at path in the response body satisfies
predicate.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValueMatching(this HttpResponseMessage response, string path, Func<JsonElement, bool> predicate, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA path of dot-separated property names and zero-based bracket indices, for example
user.age.predicateFunc<JsonElement, bool>A predicate that returns true for matching elements.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValueOneOf(HttpResponseMessage, string, double[], CancellationToken)
Asserts the value at path in the response body is a JSON
number equal to any of candidates.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValueOneOf(this HttpResponseMessage response, string path, double[] candidates, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA path of dot-separated property names and zero-based bracket indices, for example
response.code.candidatesdouble[]The acceptable numeric values.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValueOneOf(HttpResponseMessage, string, int[], CancellationToken)
Asserts the value at path in the response body is a 32-bit integer
equal to any of candidates, encoded as either a JSON number or a numeric
JSON string, for System.Text.Json or Protobuf-style int32 values.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValueOneOf(this HttpResponseMessage response, string path, int[] candidates, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA path of dot-separated property names and zero-based bracket indices, for example
response.code.candidatesint[]The acceptable 32-bit integer values.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValueOneOf(HttpResponseMessage, string, long[], CancellationToken)
Asserts the value at path in the response body is a 64-bit integer
equal to any of candidates, encoded as either a JSON number or a numeric
JSON string (parsed with InvariantCulture), for
System.Text.Json or Protobuf-style int64 values.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValueOneOf(this HttpResponseMessage response, string path, long[] candidates, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA path of dot-separated property names and zero-based bracket indices, for example
message.sequence.candidateslong[]The acceptable 64-bit integer values.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValueOneOf(HttpResponseMessage, string, string[], CancellationToken)
Asserts the value at path in the response body is a JSON
string equal (ordinal) to any of candidates.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValueOneOf(this HttpResponseMessage response, string path, string[] candidates, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA path of dot-separated property names and zero-based bracket indices, for example
health.status.candidatesstring[]The acceptable string values.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValueOneOf(HttpResponseMessage, string, uint[], CancellationToken)
Asserts the value at path in the response body is an unsigned
32-bit integer equal to any of candidates, encoded as either a JSON number
or a numeric JSON string, for System.Text.Json or Protobuf-style uint32
values.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValueOneOf(this HttpResponseMessage response, string path, uint[] candidates, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA path of dot-separated property names and zero-based bracket indices, for example
response.code.candidatesuint[]The acceptable unsigned 32-bit integer values.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValueOneOf(HttpResponseMessage, string, ulong[], CancellationToken)
Asserts the value at path in the response body is an unsigned
64-bit integer equal to any of candidates, encoded as either a JSON number
or a numeric JSON string (parsed with InvariantCulture), for
System.Text.Json or Protobuf-style uint64 values.
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValueOneOf(this HttpResponseMessage response, string path, ulong[] candidates, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA path of dot-separated property names and zero-based bracket indices, for example
message.sequence.candidatesulong[]The acceptable unsigned 64-bit integer values.
cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasJsonValueParsableAs<T>(HttpResponseMessage, string, CancellationToken)
Asserts the value at path in the response body is a JSON
string whose text parses as T via
TryParse(string, IFormatProvider, out TSelf).
[GenerateAssertion]
public static Task<AssertionResult> HasJsonValueParsableAs<T>(this HttpResponseMessage response, string path, CancellationToken cancellationToken = default) where T : IParsable<T>
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA path of dot-separated property names and zero-based bracket indices, for example
order.id.cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
Type Parameters
TThe target type implementing IParsable<TSelf>.
HasNonEmptyJsonArray(HttpResponseMessage, string, CancellationToken)
Asserts the value at the dot-separated path in the response
body is a JSON array with at least one element.
[GenerateAssertion]
public static Task<AssertionResult> HasNonEmptyJsonArray(this HttpResponseMessage response, string path, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA dot-separated property path, for example
items.cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
HasNonEmptyJsonString(HttpResponseMessage, string, CancellationToken)
Asserts the value at path in the response body is a
non-empty JSON string.
[GenerateAssertion]
public static Task<AssertionResult> HasNonEmptyJsonString(this HttpResponseMessage response, string path, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response whose body is the JSON document.
pathstringA path of dot-separated property names and zero-based bracket indices, for example
user.name.cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
MatchesProblemDetails(HttpResponseMessage, int, string?, string?, string?, string?, CancellationToken)
Asserts the response is a valid RFC 7807 ProblemDetails (Content-Type
application/problem+json, deserializable shape) and that each specified field
matches. Unspecified fields are not asserted; pass null to skip a field.
Internal mirror type avoids the Microsoft.AspNetCore.Mvc.Abstractions dependency
(Apache 2.0) so the package stays MIT-clean and AOT-clean.
[GenerateAssertion]
public static Task<AssertionResult> MatchesProblemDetails(this HttpResponseMessage response, int status, string? title = null, string? detail = null, string? type = null, string? instance = null, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response.
statusintThe expected
statusfield value.titlestringThe expected
titlefield value, or null to skip.detailstringThe expected
detailfield value, or null to skip.typestringThe expected
typeURI field value, or null to skip.instancestringThe expected
instanceURI field value, or null to skip.cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>
MatchesValidationProblemDetails(HttpResponseMessage, int, IReadOnlyDictionary<string, string[]>, string?, string?, string?, string?, CancellationToken)
Asserts the response is a valid RFC 7807 ValidationProblemDetails (the
ProblemDetails extension with an errors dictionary mapping field names to
validation messages, the ASP.NET Core convention). Both the base ProblemDetails fields
and the errors dictionary are asserted.
[GenerateAssertion]
public static Task<AssertionResult> MatchesValidationProblemDetails(this HttpResponseMessage response, int status, IReadOnlyDictionary<string, string[]> errors, string? title = null, string? detail = null, string? type = null, string? instance = null, CancellationToken cancellationToken = default)
Parameters
responseHttpResponseMessageThe HTTP response.
statusintThe expected
statusfield value.errorsIReadOnlyDictionary<string, string[]>The expected validation errors keyed by field name. Every key in this dictionary must appear in the response's errors dict with matching values.
titlestringThe expected
titlefield value, or null to skip.detailstringThe expected
detailfield value, or null to skip.typestringThe expected
typeURI field value, or null to skip.instancestringThe expected
instanceURI field value, or null to skip.cancellationTokenCancellationTokenFlows to the response-body read.
Returns
- Task<AssertionResult>