Expectations for HttpRequestMessage, HttpResponseMessage and Uri for
aweXpect.
Expectations for HttpRequestMessage:
| Expectation | Negated | Summary |
|---|---|---|
HasMethod |
has the expected HTTP method | |
HasRequestUri |
has the expected request URI | |
HasHeader |
DoesNotHaveHeader |
has a header, optionally with a value |
HasContent |
has the expected string content |
Expectations for HttpResponseMessage:
| Expectation | Negated | Summary |
|---|---|---|
HasStatusCode |
HasStatusCode().DifferentTo |
has the expected status code or status category |
HasHeader |
DoesNotHaveHeader |
has a header, optionally with a value |
HasContentType |
has the expected media type | |
HasContent |
has the expected string content | |
HasProblemDetailsContent |
has a ProblemDetails content |
|
HasRequestMessage |
the request message meets nested expectations |
Expectations for Uri:
| Expectation | Negated | Summary |
|---|---|---|
IsAbsolute |
IsNotAbsolute |
an absolute URI |
IsFile |
IsNotFile |
a file URI |
IsLoopback |
IsNotLoopback |
references the local host |
IsUnc |
IsNotUnc |
a UNC path |
HasDefaultPort |
DoesNotHaveDefaultPort |
uses the default port of its scheme |
HasScheme |
negated comparison | has the expected scheme |
When an expectation on a request or response fails, the failure message includes the formatted HTTP request and response.
You can verify that the HttpRequestMessage has the expected method:
HttpRequestMessage request = new(HttpMethod.Get, "https://music.example.com/tracks/1");
await Expect.That(request).HasMethod(HttpMethod.Get);You can verify that the HttpRequestMessage has the expected request URI:
HttpRequestMessage request = new(HttpMethod.Get, "https://music.example.com/tracks/1");
await Expect.That(request).HasRequestUri("https://music.example.com/tracks/1");
await Expect.That(request).HasRequestUri(new Uri("https://music.example.com/tracks/1"));You can verify that the HttpRequestMessage has a header, optionally with the expected value, or that it does not have
it:
HttpRequestMessage request = new(HttpMethod.Get, "https://music.example.com/tracks/1");
request.Headers.Add("Accept", "application/json");
await Expect.That(request).HasHeader("Accept");
await Expect.That(request).HasHeader("Accept").WithValue("application/json");
await Expect.That(request).DoesNotHaveHeader("Authorization");WithValue supports the same string options and
match types as comparing strings.
You can also add expectations on the header value or on all of its values:
HttpRequestMessage request = new(HttpMethod.Get, "https://music.example.com/tracks/1");
request.Headers.Add("Accept-Encoding", ["gzip", "deflate"]);
await Expect.That(request).HasHeader("Accept-Encoding")
.WhoseValues(values => values.Contains("gzip"));The failure message shows the difference and the request:
HttpRequestMessage request = new(HttpMethod.Get, "https://music.example.com/tracks/1");
request.Headers.Add("Cache-Control", "no-cache");
await Expect.That(request).HasHeader("Cache-Control").WithValue("max-age=0");Expected that request
has a "Cache-Control" header whose value is equal to "max-age=0",
but it had header value "no-cache", which differs at index 0:
↓ (actual)
"no-cache"
"max-age=0"
↑ (expected)
HTTP-Request:
GET https://music.example.com/tracks/1 HTTP/1.1
Cache-Control: no-cache
You can verify that the HttpRequestMessage has the expected string content:
HttpRequestMessage request = new(HttpMethod.Post, "https://music.example.com/tracks")
{
Content = new StringContent("{\"title\": \"Let It Be\"}"),
};
await Expect.That(request).HasContent("*Let It Be*").AsWildcard();
await Expect.That(request).HasContent(content => content.Contains("Let It Be"));The content supports the same string options and match types as comparing strings.
You can verify the status code of the HttpResponseMessage, either the exact value or its category:
HttpResponseMessage response = await httpClient.GetAsync("https://music.example.com/tracks/1");
await Expect.That(response).HasStatusCode(HttpStatusCode.OK);
await Expect.That(response).HasStatusCode().EqualTo(HttpStatusCode.OK);
await Expect.That(response).HasStatusCode().DifferentTo(HttpStatusCode.NotFound);
await Expect.That(response).HasStatusCode().Success();The categories are Success() (2xx), Redirection() (3xx), ClientError() (4xx), ServerError() (5xx) and
Error() (4xx or 5xx). Combine them with .Or to allow several:
HttpResponseMessage response = await httpClient.PostAsync("https://music.example.com/tracks", new StringContent(""));
await Expect.That(response).HasStatusCode().ClientError().Or.HasStatusCode().ServerError();A failing expectation against a test server
HttpResponseMessage response = await httpClient.GetAsync("/tracks/1");
await Expect.That(response).HasStatusCode(HttpStatusCode.NotFound);fails with the request and the response:
Expected that response
has status code 404 NotFound,
but it had status code 200 OK
HTTP-Request:
GET http://localhost/tracks/1 HTTP/1.1
HTTP-Response:
200 OK HTTP/1.1
x-vendor: VENDOR
Content-Type: application/json; charset=utf-8
Content-Length: 51
{
"id": 1,
"title": "Let It Be",
"artist": "The Beatles"
}
You can verify that the HttpResponseMessage has a header, optionally with the expected value, or that it does not
have it:
HttpResponseMessage response = await httpClient.GetAsync("https://music.example.com/tracks/1");
await Expect.That(response).HasHeader("Cache-Control");
await Expect.That(response).HasHeader("Cache-Control").WithValue("must-revalidate, max-age=0, private");
await Expect.That(response).DoesNotHaveHeader("Set-Cookie");You can also add expectations on the header value or on all of its values:
HttpResponseMessage response = await httpClient.GetAsync("https://music.example.com/tracks/1");
await Expect.That(response).HasHeader("ETag")
.WhoseValue(value => value.IsNotEmpty());
await Expect.That(response).HasHeader("Vary")
.WhoseValues(values => values.Contains("Accept-Encoding"));You can verify the media type in the Content-Type header of the HttpResponseMessage:
HttpResponseMessage response = await httpClient.GetAsync("/tracks/1");
await Expect.That(response).HasContentType("application/json");
await Expect.That(response).HasContentType("application/*").AsWildcard();HttpResponseMessage response = await httpClient.GetAsync("/tracks/1");
await Expect.That(response).HasContentType("text/plain");Expected that response
has a `Content-Type` header equal to "text/plain",
but it had content type "application/json", which differs at index 0:
↓ (actual)
"application/json"
"text/plain"
↑ (expected)
HTTP-Request:
GET http://localhost/tracks/1 HTTP/1.1
HTTP-Response:
200 OK HTTP/1.1
x-vendor: VENDOR
Content-Type: application/json; charset=utf-8
Content-Length: 51
{
"id": 1,
"title": "Let It Be",
"artist": "The Beatles"
}
You can verify that the HttpResponseMessage has the expected string content:
HttpResponseMessage response = await httpClient.GetAsync("https://music.example.com/tracks/1");
await Expect.That(response).HasContent("*Let It Be*").AsWildcard();
await Expect.That(response).HasContent(content => content.Contains("The Beatles"));The content supports the same string options and match types as comparing strings. With aweXpect.Json, the nested expectations can also verify JSON content:
HttpResponseMessage response = await httpClient.GetAsync("https://music.example.com/tracks/1");
await Expect.That(response).HasContent(content => content
.IsValidJsonMatching(new { title = "Let It Be", artist = "The Beatles" }));You can verify that the content of the HttpResponseMessage is a valid
ProblemDetails object,
optionally with the expected type, title, status, detail and instance:
HttpResponseMessage response = await httpClient.GetAsync("https://music.example.com/tracks/42");
await Expect.That(response)
.HasProblemDetailsContent("https://httpstatuses.com/404")
.WithTitle("Track not found")
.WithStatus(404)
.WithInstance("/tracks/42");The type, title, detail and instance support the same string options and match types as comparing strings.
You can add expectations on the HttpRequestMessage that led to the HttpResponseMessage:
HttpResponseMessage response = await httpClient.GetAsync("https://music.example.com/tracks/1");
await Expect.That(response).HasRequestMessage(request => request
.HasMethod(HttpMethod.Get).And
.HasRequestUri("https://music.example.com/tracks/1"));You can verify what kind of URI the Uri is, or that it is not:
Uri uri = new("https://music.example.com/tracks/1");
await Expect.That(uri).IsAbsolute();
await Expect.That(uri).IsNotFile();
await Expect.That(uri).IsNotLoopback();
await Expect.That(uri).IsNotUnc();Uri uri = new("/tracks/1", UriKind.Relative);
await Expect.That(uri).IsAbsolute();Expected that uri
is an absolute URI,
but it was /tracks/1
You can verify that the Uri uses the default port of its scheme, or that it does not:
await Expect.That(new Uri("https://music.example.com/tracks/1")).HasDefaultPort();
await Expect.That(new Uri("https://music.example.com:8443/tracks/1")).DoesNotHaveDefaultPort();You can verify the scheme of the Uri:
Uri uri = new("https://music.example.com/tracks/1");
await Expect.That(uri).HasScheme().EqualTo("https");
await Expect.That(uri).HasScheme().NotEqualTo("http");The failure messages include the content of the request and the response. Each content is formatted by the first
content processor that can handle it: by default JSON is indented, text is shown as is, and audio, image, video and
PDF content is summarized with its media type and length. You can change the processors, e.g. with your own
IContentProcessor. The value is restored when the returned lifetime is disposed:
using aweXpect.Customization;
using aweXpect.Web;
using aweXpect.Web.ContentProcessors;
using (Customize.aweXpect.Web().ContentProcessors.Set([
new MyCsvContentProcessor(),
new JsonContentProcessor(),
new StringContentProcessor(),
new BinaryContentProcessor(),
]))
{
// formats CSV content with the custom processor
}To change the processors for all tests, set them on Customize.aweXpect.Global.Web() instead.