I’m having trouble testing a module of mine. One of the things I want to test is that calling one function in the module (using certain arguments) results in a call to another function in the module. For this testing, I do not want to test the actual results of the call to the second function. There are details that are beside the point & should be tested separately.
I’ve looked at the docs (incl. mocking partials, spyOn & mockImplementation), lots of github threads (incl this one) and there are actually examples that seem like they test exactly what I want to do. However, they haven’t worked and I’m not sure what the difference in my code is.
greet.js:
export const greetAPerson(person, recognized) {
if (recognized) return greetByName(person);
return askForName(person);
}
export const greetByName(person) {
return `Hello ${person.name}`;
}
export const askForName(person) {
// real code has implementation details that I don't want to test
return 'Hello, what is your name?';
}
module.test.js
import * as greet from './greet';
describe('greetings', () => {
afterAll(() => {
jest.restoreAllMocks();
});
// passes
test('returns greeting by name for known person', () => {
const greeting = greet.greetAPerson({ name: 'Batman' }, true);
expect(greeting).toBe('Hello Batman');
});
// passes
test('greeting an un-regognized person returns request for their name', () => {
const greeting = greet.greetAPerson({ name: '' }, false);
expect(greeting).toBe('Hello, what is your name?');
});
// fails
test('greeting an un-regognized person calls askForName (spyOn)', () => {
const spiedAskForName = jest.spyOn(greet, 'askForName');
greet.greetAPerson({ name: '' }, false);
expect(spiedAskForName).toBeCalled();
});
// fails
test('greeting an un-regognized person calls askForName (spyOn + mockImplmentation)', () => {
const spiedAskForName = jest.spyOn(greet, 'askForName').mockImplementation(() => 'who are you?');
greet.greetAPerson({ name: '' }, false);
expect(spiedAskForName).toBeCalled();
});
// fails
test('greeting an un-regognized person returns mocked value (spyOn + mockImplmentation)', () => {
jest.spyOn(greet, 'askForName').mockImplementation(() => 'who are you?');
const greeting = greet.greetAPerson({ name: '' }, false);
expect(greeting).toBe('who are you?');
});
// fails
test('greeting an un-regognized person calls askForName: jest.fn()', () => {
greet.askForName = jest.fn();
greet.greetAPerson({ name: '' }, false);
expect(greet.askForName).toBeCalled();
});
// fails
test('mock entire module, except most of it', () => {
jest.mock('./greet', () => {
const greet = jest.requireActual('./greet');
return {
__esModule: true,
...greet,
askForName: jest.fn(() => 'who are you?')
};
});
const greeting = greet.greetAPerson({ name: '' }, false);
expect(greeting).toBe('who are you?');
});
});
Any ideas what I’m doing wrong?