Skip to content

[Feature] Allow mocking third party and built-in modules (for non-E2E tests) #14572

@patricktree

Description

@patricktree

Feature Request

Playwright Test can also be used as a "generic" test runner to run unit/integration tests (see #14268).
For such tests it is often helpful, if not necessary, to mock modules loaded by CJS require or ESM import statements. This allows to test a module in isolation.

At the moment, Playwright does not have a way to replace modules with mocks when they get loaded. As discussed in #14398, Node.js solutions to mock modules like proxyquire or testdouble cannot be used because Playwright has a custom implementation to load modules (for technical reasons) and therefore these solutions don't work.

It would be great if Playwright Test would have some sort of API to mock CJS/ESM modules, similar to the things testdouble is capable of.
Their documentation shows that there would be some things to think through, for example:

  • is it possible to replace a module after the subject under test was imported/required?
  • is it possible to access (parts of) the original implementation after a module mock was applied?
  • should there be an API to "reset" mocked modules?

Idea

Example is derived from https://jestjs.io/docs/mock-functions#mocking-modules, API inspired by https://github.com/testdouble/testdouble.js#specifying-a-custom-replacement.

users.ts:

import axios from 'axios';

class Users {
  static all() {
    return axios.get('/users.json').then((resp) => resp.data);
  }
}

export default Users;

my-test.spec.ts:

import { test, mock } from '@playwright/test';

import Users from './users';

test('should fetch users', async ({}) => {
  const fakeUsers = [{ name: 'Bob' }];
  /* mock axios.get (would be great if that works even though ./users was imported already */
  mock.replace('axios', {
    get: mock.func(() => Promise.resolve({ data: fakeUsers })),
  });

  const actualUsers = await Users.all();
  expect(actualUsers).toEqual(fakeUsers);
});

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions