OpraTestClient
OpraTestClient is a test-specific HTTP client that sends requests directly to your application handler without binding a port. There is no server to start or stop between tests; the client closes the connection after each request.
Constructor
import { OpraTestClient } from '@opra/testing';
const testClient = new OpraTestClient(app, options?);
| Parameter | Type | Description |
|---|---|---|
app | Server | RequestListener | The HTTP server or (req, res) => void handler to test |
options | OpraTestClient.Options | Optional. Extends FetchBackend.Options with an optional basePath |
Making requests
Every HTTP method returns an HttpRequestObservable. Call .getResponse() to resolve it and get back an HttpResponse with an .expect property pre-attached.
const res = await testClient.get('/customers').getResponse();
const res = await testClient.post('/customers', body).getResponse();
const res = await testClient.patch('/customers@42', body).getResponse();
const res = await testClient.delete('/customers@42').getResponse();
Chain .param() and .header() before .getResponse():
const res = await testClient
.get('/customers')
.param({ limit: 10, sort: ['familyName'] })
.header('X-Tenant-Id', tenantId)
.getResponse();
Setup pattern
Initialise a single TestApp instance per describe block and tear it down afterwards:
import { OpraTestClient } from '@opra/testing';
import { TestApp } from '#test-app';
describe('e2e: /Customers', () => {
let testApp: TestApp;
let testClient: OpraTestClient;
before(async () => {
testApp = await TestApp.create();
testClient = testApp.client;
});
after(() => testApp?.close());
beforeEach(() => testApp?.restoreUser());
afterEach(() => testApp?.restoreUser());
});
TestApp is a thin wrapper your project owns — it boots the application, exposes client and moduleRef, and provides helpers like restoreUser() to reset per-test state.
Testing authentication
Set testApp.user._id to an empty string to simulate an unauthenticated (anonymous) request:
it('Should reject anonymous requests', async () => {
testApp.user._id = '';
const res = await testClient.get('/organizations').getResponse();
res.expect.toFail(HttpStatusCode.UNAUTHORIZED);
});
Testing authorization
Set testApp.user.roles to control which roles are active:
it('Should permit SUPPORT_USER', async () => {
testApp.user.roles = [UserRole.SUPPORT_USER];
const res = await testClient.get('/organizations').getResponse();
res.expect.toSuccess(HttpStatusCode.OK).toReturnCollection();
});
it('Should forbid ORGANIZATION_OWNER', async () => {
testApp.user.roles = [UserRole.ORGANIZATION_OWNER];
const res = await testClient.get('/organizations').getResponse();
res.expect.toFail(HttpStatusCode.FORBIDDEN);
});
testApp.restoreUser() — called in beforeEach and afterEach — resets user state so tests do not leak into each other.