Skip to content

Commit

Permalink
fix(jest-mock): prevent mockImplementationOnce bleeding into `withI…
Browse files Browse the repository at this point in the history
…mplementation` (#13888)
  • Loading branch information
mrazauskas committed Feb 10, 2023
1 parent d97b760 commit 0d69a73
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@
### Fixes

- `[jest-mock]` Clear mock state when `jest.restoreAllMocks()` is called ([#13867](https://github.com/facebook/jest/pull/13867))
- `[jest-mock]` Prevent `mockImplementationOnce` and `mockReturnValueOnce` bleeding into `withImplementation` ([#13888](https://github.com/facebook/jest/pull/13888))

### Chore & Maintenance

Expand Down
32 changes: 32 additions & 0 deletions packages/jest-mock/src/__tests__/index.test.ts
Expand Up @@ -1143,6 +1143,38 @@ describe('moduleMocker', () => {

expect.assertions(4);
});

it('mockImplementationOnce does not bleed into withImplementation', () => {
const mock = jest
.fn(() => 'outside callback')
.mockImplementationOnce(() => 'once');

mock.withImplementation(
() => 'inside callback',
() => {
expect(mock()).toBe('inside callback');
},
);

expect(mock()).toBe('once');
expect(mock()).toBe('outside callback');
});

it('mockReturnValueOnce does not bleed into withImplementation', () => {
const mock = jest
.fn(() => 'outside callback')
.mockReturnValueOnce('once');

mock.withImplementation(
() => 'inside callback',
() => {
expect(mock()).toBe('inside callback');
},
);

expect(mock()).toBe('once');
expect(mock()).toBe('outside callback');
});
});

test('mockReturnValue does not override mockImplementationOnce', () => {
Expand Down
4 changes: 4 additions & 0 deletions packages/jest-mock/src/index.ts
Expand Up @@ -840,16 +840,20 @@ export class ModuleMocker {
// Remember previous mock implementation, then set new one
const mockConfig = this._ensureMockConfig(f);
const previousImplementation = mockConfig.mockImpl;
const previousSpecificImplementations = mockConfig.specificMockImpls;
mockConfig.mockImpl = fn;
mockConfig.specificMockImpls = [];

const returnedValue = callback();

if (isPromise(returnedValue)) {
return returnedValue.then(() => {
mockConfig.mockImpl = previousImplementation;
mockConfig.specificMockImpls = previousSpecificImplementations;
});
} else {
mockConfig.mockImpl = previousImplementation;
mockConfig.specificMockImpls = previousSpecificImplementations;
}
}

Expand Down

0 comments on commit 0d69a73

Please sign in to comment.