Testing

Use createTestEnv() from svelte-realtime/test to test your live functions without a real WebSocket server.

import { describe, it, expect, afterEach } from 'vitest';
import { createTestEnv } from 'svelte-realtime/test';
import * as chat from '../src/live/chat.js';

describe('chat module', () => {
  const env = createTestEnv();
  afterEach(() => env.cleanup());

  it('sends and receives messages', async () => {
    env.register('chat', chat);

    const alice = env.connect({ id: 'alice', name: 'Alice' });
    const bob = env.connect({ id: 'bob', name: 'Bob' });

    // Subscribe Bob to the messages stream
    const stream = bob.subscribe('chat/messages');
    await new Promise(r => setTimeout(r, 10));

    // Alice sends a message
    const msg = await alice.call('chat/sendMessage', 'Hello!');
    expect(msg.text).toBe('Hello!');

    // Bob receives the live update
    await new Promise(r => setTimeout(r, 10));
    expect(stream.events).toHaveLength(1);
  });
});

TestEnv API

MethodDescription
register(moduleName, exports)Register a module’s live functions
connect(userData)Create a fake connected client
cleanup()Clear all state (call in afterEach)
platformThe mock platform object

TestClient API

MethodDescription
call(path, ...args)Call a live() function
subscribe(path, ...args)Subscribe to a live.stream()
binary(path, buffer, ...args)Call a live.binary() function
disconnect() / reconnect()Simulate connection state changes

TestStream API

PropertyDescription
valueLatest value from the stream
errorError if the stream failed
topicThe topic the stream is subscribed to
eventsAll pub/sub events received
hasMoreWhether more pages are available
waitFor(predicate, timeout?)Wait for a value matching a predicate

Integration testing your hooks.ws with a real WebSocket server

For tests that exercise the upgrade handshake, subscribe protocol, and pub/sub end-to-end, use createTestServer() from svelte-adapter-uws/testing. It boots a real uWebSockets.js server on a random port (typically in ~2ms) and exposes the full Platform API.

import { createTestServer } from 'svelte-adapter-uws/testing';
import { WebSocket } from 'ws';
import { describe, it, expect, afterEach } from 'vitest';
import * as myHandler from '../src/hooks.ws.js';

let server;
afterEach(() => server?.close());

it('rejects unauthenticated upgrades', async () => {
  server = await createTestServer({ handler: myHandler });

  const ws = new WebSocket(server.wsUrl);
  const code = await new Promise((resolve) => {
    ws.on('unexpected-response', (_, res) => resolve(res.statusCode));
    ws.on('open', () => resolve('open'));
  });
  expect(code).toBe(401);
});

it('publishes to subscribers', async () => {
  server = await createTestServer({ handler: myHandler });

  const ws = new WebSocket(server.wsUrl, {
    headers: { cookie: 'session=valid-token' }
  });
  await new Promise(r => ws.on('open', r));

  ws.send(JSON.stringify({ type: 'subscribe', topic: 'todos' }));
  await new Promise(r => setTimeout(r, 10));

  const msg = new Promise(r => ws.on('message', d => r(JSON.parse(d.toString()))));
  server.platform.publish('todos', 'created', { id: 1 });
  expect(await msg).toMatchObject({ topic: 'todos', event: 'created' });

  ws.close();
});

The test server uses the same subscribe / unsubscribe protocol as production and exposes publish, send, sendTo, topic, connections, and subscribers via server.platform. Use createTestEnv() (above) for fast in-memory unit tests of live() modules; reach for createTestServer() when you need to exercise hooks.ws, the upgrade path, or the wire protocol.

Was this page helpful?