A collection of test utilities specifically designed for LoopBack 4 applications and TypeScript testing
npx @tessl/cli install tessl/npm-loopback--testlab@8.0.0LoopBack TestLab is a comprehensive collection of testing utilities specifically designed for LoopBack 4 applications and TypeScript testing in general. It provides behavior-driven development (BDD) style assertions, complete Sinon.js integration, HTTP request/response stubs, supertest helpers, OpenAPI validation, test sandbox utilities, and various helper functions for robust test suite development.
npm install @loopback/testlabimport { expect, sinon, createClientForHandler, TestSandbox } from "@loopback/testlab";For CommonJS:
const { expect, sinon, createClientForHandler, TestSandbox } = require("@loopback/testlab");import { expect, sinon, TestSandbox, createClientForHandler } from "@loopback/testlab";
// BDD-style assertions
expect(5).to.be.greaterThan(3);
expect([1, 2, 3]).to.have.lengthOf(3);
expect({name: "Alice"}).to.have.property("name", "Alice");
// Sinon integration for test doubles
const stub = sinon.stub();
stub.returns("mock result");
expect(stub()).to.equal("mock result");
// Test sandbox for file operations
const sandbox = new TestSandbox("/tmp/tests");
await sandbox.writeTextFile("config.json", JSON.stringify({test: true}));
await sandbox.reset();
// HTTP client testing
const client = createClientForHandler((req, res) => {
res.writeHead(200, {"Content-Type": "application/json"});
res.end(JSON.stringify({message: "Hello"}));
});
await client.get("/").expect(200).expect({message: "Hello"});LoopBack TestLab is organized into distinct functional modules:
Behavior-driven development style assertions using Should.js configured in as-function mode with enhanced TypeScript support and chai-like syntax.
const expect: Internal;
interface Internal extends ShouldInternal {
(obj: any): ShouldAssertion;
use(fn: (should: Internal, Assertion: Assertion) => void): Internal;
}Complete Sinon.js integration for spies, stubs, and mocks with enhanced TypeScript experience and improved stubbing utilities.
const sinon: sinon.SinonStatic;
type SinonSpy = sinon.SinonSpy;
function createStubInstance<TType extends object>(
constructor: sinon.StubbableType<TType>
): StubbedInstanceWithSinonAccessor<TType>;
type StubbedInstanceWithSinonAccessor<T> = T & {
stubs: sinon.SinonStubbedInstance<T>;
};SuperTest integration and utilities for creating HTTP clients for testing REST applications and request handlers.
const supertest: typeof import("supertest");
type Client = supertest.SuperTest<supertest.Test>;
function createClientForHandler(
handler: (req: http.IncomingMessage, res: http.ServerResponse) => void
): Client;
function createRestAppClient(app: RestApplicationLike): Client;Shot-based HTTP request/response stubs for testing without running servers, including Express-specific context stubbing.
function inject(
dispatchFunc: ShotListener,
options: ShotRequestOptions
): Promise<ResponseObject>;
function stubServerRequest(options: ShotRequestOptions): IncomingMessage;
function stubServerResponse(request: IncomingMessage, onEnd: ShotCallback): ServerResponse;
function stubHandlerContext(requestOptions?: ShotRequestOptions): HandlerContextStub;
function stubExpressContext(requestOptions?: ShotRequestOptions): ExpressContextStub;File system utilities for creating isolated test directories and managing test data with automatic cleanup capabilities.
class TestSandbox {
constructor(rootPath: string, options?: TestSandboxOptions);
get path(): string;
reset(): Promise<void>;
delete(): Promise<void>;
mkdir(dir: string): Promise<void>;
copyFile(src: string, dest?: string, transform?: (content: string) => string): Promise<void>;
writeJsonFile(dest: string, data: unknown): Promise<void>;
writeTextFile(dest: string, data: string): Promise<void>;
}Async HTTP/HTTPS request utilities and server configuration helpers for test environments.
function httpGetAsync(urlString: string, agent?: http.Agent): Promise<IncomingMessage>;
function httpsGetAsync(urlString: string, agent?: https.Agent): Promise<IncomingMessage>;
function givenHttpServerConfig<T extends HttpOptions | HttpsOptions>(
customConfig?: T
): HostPort & T;OpenAPI/Swagger specification validation, JSON conversion utilities, test skipping helpers, and HTTP error logging.
function validateApiSpec(spec: any): Promise<void>;
function toJSON<T>(value: T): T;
function skipIf<ARGS extends unknown[], RETVAL>(
skip: boolean,
verb: TestDefinition<ARGS, RETVAL> & {skip: TestDefinition<ARGS, RETVAL>},
name: string,
...args: ARGS
): RETVAL;
function skipOnTravis<ARGS extends unknown[], RETVAL>(
verb: TestDefinition<ARGS, RETVAL> & {skip: TestDefinition<ARGS, RETVAL>},
name: string,
...args: ARGS
): RETVAL;interface TestSandboxOptions {
subdir: boolean | string;
}
interface RestApplicationLike {
restServer: RestServerLike;
}
interface RestServerLike {
url?: string;
rootUrl?: string;
}
interface HttpOptions extends ListenOptions {
protocol?: 'http';
}
interface HttpsOptions extends ListenOptions, HttpsServerOptions {
protocol: 'https';
}
interface HostPort {
host: string;
port: number;
}
type TestDefinition<ARGS extends unknown[], RETVAL> = (
name: string,
...args: ARGS
) => RETVAL;