Skip to content

Testing endpoints

To verify that your TypedRest endpoint configuration issues the correct HTTP requests and correctly deserializes responses, use a mock HTTP server. This lets you write fast, deterministic tests without a running API server.

Install RichardSzalay.MockHttp to intercept HttpClient calls:

dotnet add package RichardSzalay.MockHttp

Inject a MockHttpMessageHandler into HttpClient and pass it to your entry endpoint:

var mock = new MockHttpMessageHandler();
var client = new EntryEndpoint(new HttpClient(mock), new Uri("http://localhost/"));
var endpoint = new ElementEndpoint<Contact>(client, "contacts/1");

mock.Expect(HttpMethod.Get, "http://localhost/contacts/1")
    .Respond("application/json", """{"name":"Smith"}""");

var contact = await endpoint.ReadAsync();
Assert.Equal("Smith", contact.Name);

mock.VerifyNoOutstandingExpectation();

To verify a request body, use .WithContent():

mock.Expect(HttpMethod.Put, "http://localhost/contacts/1")
    .WithContent("""{"name":"Smith"}""")
    .Respond("application/json", """{"name":"Smith"}""");

await endpoint.SetAsync(new Contact { Name = "Smith" });

Install MockWebServer and point your entry endpoint at the mock server's URL:

MockWebServer server = new MockWebServer();

EntryEndpoint client = new EntryEndpoint(URI.create(server.url("/").toString()));
ElementEndpoint<Contact> endpoint = new ElementEndpointImpl<>(client, "contacts/1", Contact.class);

server.enqueue(new MockResponse()
    .setBody("{\"name\":\"Smith\"}")
    .addHeader("Content-Type", "application/json"));

Contact contact = endpoint.read();
assertEquals("Smith", contact.getName());

RecordedRequest request = server.takeRequest();
assertEquals("GET", request.getMethod());
assertEquals("/contacts/1", request.getPath());

server.close();

To verify a request body:

server.enqueue(new MockResponse()
    .setBody("{\"name\":\"Smith\"}")
    .addHeader("Content-Type", "application/json"));

endpoint.set(new Contact("Smith"));

RecordedRequest request = server.takeRequest();
assertEquals("PUT", request.getMethod());
assertEquals("{\"name\":\"Smith\"}", request.getBody().readUtf8());

Install MockWebServer and point your entry endpoint at the mock server's URL:

val server = MockWebServer()

val client = EntryEndpoint(server.url("/").toUri())
val endpoint = ElementEndpointImpl(client, "contacts/1", Contact::class.java)

server.enqueue(MockResponse()
    .setBody("""{"name":"Smith"}""")
    .addHeader("Content-Type", "application/json"))

val contact = endpoint.read()
assertEquals("Smith", contact.name)

val request = server.takeRequest()
assertEquals("GET", request.method)
assertEquals("/contacts/1", request.path)

server.close()

To verify a request body:

server.enqueue(MockResponse()
    .setBody("""{"name":"Smith"}""")
    .addHeader("Content-Type", "application/json"))

endpoint.set(Contact("Smith"))

val request = server.takeRequest()
assertEquals("PUT", request.method)
assertEquals("""{"name":"Smith"}""", request.body.readUtf8())

Install jest-fetch-mock to intercept fetch calls:

npm install --save-dev jest-fetch-mock

Enable mocking in your test setup and use mockOnceIf to queue responses:

import fetchMock from 'jest-fetch-mock';

fetchMock.enableMocks();

beforeEach(() => fetchMock.resetMocks());

test('read contact', async () => {
    const client = new EntryEndpoint('http://localhost/');
    const endpoint = new ElementEndpoint<Contact>(client, 'contacts/1');

    fetchMock.mockOnceIf(
        'http://localhost/contacts/1',
        '{"name":"Smith"}',
        { headers: { 'Content-Type': 'application/json' } }
    );

    const contact = await endpoint.read();
    expect(contact.name).toBe('Smith');
});

To verify a request body:

test('set contact', async () => {
    fetchMock.mockOnceIf(
        req => req.method === 'PUT' && req.url === 'http://localhost/contacts/1',
        async req => {
            expect(await req.text()).toBe('{"name":"Smith"}');
            return { body: '{"name":"Smith"}', headers: { 'Content-Type': 'application/json' } };
        }
    );

    await endpoint.set({ name: 'Smith' });
});