-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
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);
});