Skip to content

Commit 92c0a0a

Browse files
authored
Merge pull request #111 from skovhus/fix-fallback-mock-implementation
Correct pass fallbackMockImplementation
2 parents 63c027b + 02eb750 commit 92c0a0a

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

src/CalledWithFn.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ function isJestAsymmetricMatcher(obj: any): obj is JestAsymmetricMatcher {
1313
return !!obj && typeof obj === 'object' && 'asymmetricMatch' in obj && typeof obj.asymmetricMatch === 'function';
1414
}
1515

16-
const checkCalledWith = <T, Y extends any[]>(calledWithStack: CalledWithStackItem<T, Y>[], actualArgs: Y): T => {
17-
const calledWithInstance = calledWithStack.find(instance =>
16+
const checkCalledWith = <T, Y extends any[]>(
17+
calledWithStack: CalledWithStackItem<T, Y>[],
18+
actualArgs: Y,
19+
fallbackMockImplementation?: (...args: Y) => T
20+
): T => {
21+
const calledWithInstance = calledWithStack.find((instance) =>
1822
instance.args.every((matcher, i) => {
1923
if (matcher instanceof Matcher) {
2024
return matcher.asymmetricMatch(actualArgs[i]);
@@ -29,7 +33,9 @@ const checkCalledWith = <T, Y extends any[]>(calledWithStack: CalledWithStackIte
2933
);
3034

3135
// @ts-ignore cannot return undefined, but this will fail the test if there is an expectation which is what we want
32-
return calledWithInstance ? calledWithInstance.calledWithFn(...actualArgs) : undefined;
36+
return calledWithInstance
37+
? calledWithInstance.calledWithFn(...actualArgs)
38+
: fallbackMockImplementation && fallbackMockImplementation(...actualArgs);
3339
};
3440

3541
export const calledWithFn = <T, Y extends any[]>({
@@ -42,9 +48,10 @@ export const calledWithFn = <T, Y extends any[]>({
4248
// We create new function to delegate any interactions (mockReturnValue etc.) to for this set of args.
4349
// If that set of args is matched, we just call that jest.fn() for the result.
4450
const calledWithFn = jest.fn(fallbackMockImplementation);
45-
if (!fn.getMockImplementation()) {
51+
const mockImplementation = fn.getMockImplementation();
52+
if (!mockImplementation || mockImplementation === fallbackMockImplementation) {
4653
// Our original function gets a mock implementation which handles the matching
47-
fn.mockImplementation((...args: Y) => checkCalledWith(calledWithStack, args));
54+
fn.mockImplementation((...args: Y) => checkCalledWith(calledWithStack, args, fallbackMockImplementation));
4855
calledWithStack = [];
4956
}
5057
calledWithStack.unshift({ args, calledWithFn });

src/Mock.spec.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ describe('jest-mock-extended', () => {
244244
mockObj.getSomethingWithArgs.calledWith(1, 2).mockReturnValue(3);
245245

246246
expect(mockObj.getSomethingWithArgs(1, 2)).toBe(3);
247-
})
247+
});
248248

249249
test('Support jest matcher', () => {
250250
const mockObj = mock<MockInt>();
@@ -328,7 +328,9 @@ describe('jest-mock-extended', () => {
328328
throw new Error('not mocked');
329329
},
330330
});
331+
mockObj.deepProp.getAnotherString.calledWith('foo'); // no mock implementation
331332
expect(() => mockObj.getNumber()).toThrowError('not mocked');
333+
expect(() => mockObj.deepProp.getAnotherString('foo')).toThrowError('not mocked');
332334
});
333335

334336
test('fallback mock implementation can be overridden while also providing a mock implementation', () => {
@@ -344,8 +346,12 @@ describe('jest-mock-extended', () => {
344346
},
345347
}
346348
);
349+
mockObj.deepProp.getAnotherString.calledWith('?').mockReturnValue('mocked');
347350
expect(mockObj.getNumber()).toBe(150);
351+
expect(mockObj.deepProp.getAnotherString('?')).toBe('mocked');
352+
348353
expect(() => mockObj.deepProp.getNumber(1)).toThrowError('not mocked');
354+
expect(() => mockObj.deepProp.getAnotherString('!')).toThrowError('not mocked');
349355
});
350356
});
351357

0 commit comments

Comments
 (0)