Testing with the SDK
Flag Definitions
Raw flag calls repeat key strings and value types across every test that touches them. A flag definition declares the key pattern and the type once, and every test gets autocompletion, type checking, and one place to change when the key structure evolves.
Defining a flag
defineFlag takes a human description and a key pattern. Placeholders in braces become parameters:
const userStatus = mocko
.defineFlag<string>('User status')
.pattern('users:{id}:status');
await userStatus.set('123', 'active');
expect(await userStatus.get('123')).toBe('active');
expect(userStatus.key('123')).toBe('users:123:status');
await userStatus.delete('123');The type parameter flows through everything: get returns string | undefined here, and set rejects anything that is not a string.
Zero, one, or many placeholders
The pattern decides the call shape. No placeholders means no key arguments:
const checkoutEnabled = mocko
.defineFlag<boolean>('Checkout enabled')
.pattern('features:checkout');
await checkoutEnabled.set(true);
expect(await checkoutEnabled.get()).toBe(true);One placeholder takes a single positional string, as in userStatus above. Two or more take a params object, so call sites stay unambiguous:
const userPreference = mocko
.defineFlag<string>('User preference')
.pattern('users:{id}:preferences:{preference}');
await userPreference.set({ id: '123', preference: 'language' }, 'en');A flags module for the suite
Definitions shine when they live in one shared module next to the client. It reads like a catalog of everything your mocked environment can simulate:
// fixtures/mocko.ts
import { MockoClient } from '@mocko/sdk';
export const mocko = new MockoClient('http://localhost:8080');
export const userStatus = mocko
.defineFlag<string>('User status served by GET /users/:id')
.pattern('users:{id}:status');
export const paymentOutage = mocko
.defineFlag<boolean>('Forces 503 on all payment endpoints')
.pattern('outages:payments');import { paymentOutage } from './fixtures/mocko';
it('retries when the payment provider is down', async () => {
await paymentOutage.set(true);
const result = await app.checkout(cart);
expect(result.attempts).toBeGreaterThan(1);
});TTLs
SDK-written flags default to a 300 second TTL, so test state cleans itself up. Override it at whichever level fits:
// Client-wide default, in seconds
const mocko = new MockoClient('http://localhost:8080', {
defaultFlagTtl: 60,
});
// Per definition: derives a new definition with its own TTL
const shortLivedStatus = userStatus.ttl(30);
await shortLivedStatus.set('123', 'active');
// Per raw write
await mocko.setFlag('users:123:status', 'active', 30);Behavior details
ttl()returns a new definition; the original is unchanged, so a shared catalog stays safe to derive from inside one test.key(...)renders the concrete key without touching the server, useful for assertions and for debugging what a pattern produces.- Definitions are client-side declarations only; nothing is registered on the Mocko instance. The server just sees flag reads and writes.
Next
Local instances need no credentials, but shared ones might. Continue to Auth and Deployment.