Skip to main content

Testing Overview

Nodecord supports two levels of testing, neither of which requires a live Discord connection.

LevelWhat it testsTool
UnitA single service or command class in isolationPlain instantiation + vitest spies
E2EA module or the full bot through the real pipelineTestingModule + TestingDjsAdapter

Unit tests

Services and commands are plain TypeScript classes. Instantiate them directly and stub their dependencies, no framework involved:

import { vi } from 'vitest';
import { PingCommand } from './ping.command';
import { PingService } from './ping.service';

describe('PingCommand', () => {
let command: PingCommand;

beforeEach(() => {
const service = { getPong: vi.fn().mockReturnValue('Pong! Hello, test!') };
command = new PingCommand(service);
});

it('returns pong message', () => {
expect(command.execute()).toBe('Pong! Hello, test!');
});
});

E2E tests

Use TestingDjsAdapter to run the full command pipeline without Discord. You can pass the root module directly, or use TestingModule to override specific providers:

// Full bot, real providers
NodecordClient.create({ module: BotModule, adapter, options: { logger: false } });

// Scoped module, mocked providers
const testingModule = TestingModule.create(AdminModule).overrideProvider(AdminService, adminServiceMock).build();

NodecordClient.create({
module: testingModule,
adapter: TestingDjsAdapter,
options: { logger: false },
});

Next steps