Session Mocking
The mock helpers let you inject pre-set session/state values into a bot's context without needing real storage middleware.
mockSession
Mocks ctx.session for per-user session state.
import { mockSession, prepareBot } from 'grammy-testing';
import { Bot } from 'grammy';
interface MySession {
count: number;
}
const { session, mockSessionMiddleware } = mockSession<MySession, MyContext>({ count: 0 });
const bot = new Bot<MyContext>('token');
bot.use(mockSessionMiddleware); // install before your handlers
bot.command('count', async (ctx) => {
ctx.session.count += 1;
await ctx.reply(`Count: ${ctx.session.count}`);
});
const { chats } = await prepareBot(bot);
const user = chats.newUser();
await user.sendCommand('/count');
await user.sendCommand('/count');
expect(user.replies.lastOrThrow().text).toBe('Count: 2');
expect(session.count).toBe(2); // mutate or read directlyThe session object is the same mutable reference injected into ctx.session. You can read and write it directly in your test.
mockChatSession
Mocks ctx.chatSession for per-chat session state.
interface ChatSettings {
language: string;
}
const { chatSession, mockChatSessionMiddleware } = mockChatSession<ChatSettings, MyContext>({
language: 'en',
});
bot.use(mockChatSessionMiddleware);mockState
Pre-populates ctx.state before every handler invocation. Available via prepareComposer and prepareMiddleware options, or manually:
import { mockState } from 'grammy-testing';
interface MyState {
isAdmin: boolean;
}
const { state, mockStateMiddleware } = mockState<MyState, MyContext>({ isAdmin: true });
bot.use(mockStateMiddleware);
// Or via prepareComposer:
const { chats } = await prepareComposer(composer, {
state: { isAdmin: true },
});mockContextField
Generic helper for mocking any context field. The specialised helpers above are built on it.
import { mockContextField } from 'grammy-testing';
interface MyContext extends Context {
premium: boolean;
}
const { mocked, middleware } = mockContextField<MyContext, 'premium'>('premium', true);
bot.use(middleware);
// ctx.premium === true for every updateCombining with real session middleware
You can use mockSession alongside grammY's real session() middleware to pre-seed state while keeping real per-chat storage:
const { mockSessionMiddleware } = mockSession({ count: 5 });
bot.use(mockSessionMiddleware); // runs first — seeds state
// ... bot.use(session({ ... })) would override thisOr skip mockSession entirely and use grammY's session() with an in-memory adapter — both approaches work fine with grammY Testing.