close

Mock functions

Rstest provides some utility functions to help you mock functions powered by tinyspy.

rstest.fn

  • Alias: rs.fn
  • Type:
export interface Mock<T extends Function> extends MockInstance<T> {
  (...args: Parameters<T>): ReturnType<T>;
}

export type MockFn = <T extends Function>(fn?: T) => Mock<T>;

Creates a spy on a function.

const sayHi = rstest.fn((name: string) => `hi ${name}`);

const res = sayHi('bob');

expect(res).toBe('hi bob');

expect(sayHi).toHaveBeenCalledTimes(1);

rstest.spyOn

  • Alias: rs.spyOn
  • Type:
export type SpyFn = (
  obj: Record<string, any>,
  methodName: string,
  accessType?: 'get' | 'set',
) => MockInstance;

Creates a spy on a method of an object.

const sayHi = () => 'hi';
const hi = {
  sayHi,
};

const spy = rstest.spyOn(hi, 'sayHi');

expect(hi.sayHi()).toBe('hi');

expect(spy).toHaveBeenCalled();

rstest.isMockFunction

  • Alias: rs.isMockFunction
  • Type: (fn: any) => fn is MockInstance

Determines if the given function is a mocked function.

rstest.mockObject

  • Alias: rs.mockObject
  • Type:
type MockObject = <T>(
  object: T,
  options?: { spy?: boolean },
) => MaybeMockedDeep<T>;

Creates a deep mock of an object. All methods are replaced with mock functions, while primitive values and plain objects are preserved.

Basic usage

const original = {
  method() {
    return 42;
  },
  nested: {
    getValue() {
      return 'real';
    },
  },
  prop: 'foo',
};

const mocked = rstest.mockObject(original);

// Methods return undefined by default
expect(mocked.method()).toBe(undefined);
expect(mocked.nested.getValue()).toBe(undefined);

// Primitive values are preserved
expect(mocked.prop).toBe('foo');

// Methods are mock functions
expect(rstest.isMockFunction(mocked.method)).toBe(true);

Mocking return values

You can configure mocked methods to return specific values:

const mocked = rstest.mockObject({
  fetchData: () => 'real data',
});

mocked.fetchData.mockReturnValue('mocked data');

expect(mocked.fetchData()).toBe('mocked data');

Spy mode

When { spy: true } is passed as the second argument, the original implementations are preserved while still tracking calls:

const original = {
  add: (a: number, b: number) => a + b,
};

const spied = rstest.mockObject(original, { spy: true });

// Original implementation is preserved
expect(spied.add(1, 2)).toBe(3);

// Calls are tracked
expect(spied.add).toHaveBeenCalledWith(1, 2);
expect(spied.add.mock.results[0]).toEqual({ type: 'return', value: 3 });

Arrays

By default, arrays are replaced with empty arrays. With { spy: true }, arrays keep their original values:

const mocked = rstest.mockObject({ array: [1, 2, 3] });
expect(mocked.array).toEqual([]);

const spied = rstest.mockObject({ array: [1, 2, 3] }, { spy: true });
expect(spied.array).toEqual([1, 2, 3]);

Mocking classes

You can also mock class constructors. Use { spy: true } to preserve the original class behavior while tracking calls:

class UserService {
  getUser() {
    return { id: 1, name: 'Alice' };
  }
}

// Use { spy: true } to keep original implementation
const MockedService = rstest.mockObject(UserService, { spy: true });
const instance = new MockedService();

// Original method works
expect(instance.getUser()).toEqual({ id: 1, name: 'Alice' });

// Override the implementation
rs.mocked(instance.getUser).mockImplementation(() => ({ id: 2, name: 'Bob' }));
expect(instance.getUser()).toEqual({ id: 2, name: 'Bob' });

rstest.mocked

  • Alias: rs.mocked
  • Type:
type Mocked = <T>(
  item: T,
  deep?: boolean | { partial?: boolean; deep?: boolean },
) => MaybeMockedDeep<T>;

A type helper for TypeScript that wraps an object with mock types without changing its runtime behavior. This is useful when you have mocked a module and want proper type hints for the mock methods.

import { myModule } from './myModule';

rs.mock('./myModule');

// TypeScript now knows myModule.method is a MockInstance
const mockedModule = rstest.mocked(myModule);

mockedModule.method.mockReturnValue('mocked');

The function simply returns the same object at runtime - it only affects TypeScript types.

rstest.clearAllMocks

  • Alias: rs.clearAllMocks
  • Type: () => Rstest

Clears the mock.calls, mock.instances, mock.contexts and mock.results properties of all mocks.

rstest.resetAllMocks

  • Alias: rs.resetAllMocks
  • Type: () => Rstest

Clears all mocks properties and reset each mock's implementation to its original.

rstest.restoreAllMocks

  • Alias: rs.restoreAllMocks
  • Type: () => Rstest

Reset all mocks and restore original descriptors of spied-on objects.

More