You can spy the class instance methods:
it("Testing", () => {
// Some mock data passed below
const obj = new myClass();
const spyA = jest.spyOn(obj, "_methodA").mockReturnValue({});
const spyB = jest.spyOn(obj, "_methodB").mockReturnValue({});
obj.main();
expect(spyA).toHaveBeenCalledTimes(1);
expect(spyB).toHaveBeenCalledTimes(1);
});
You can spy the class methods:
it("Testing", () => {
// Some mock data passed below
const spyA = jest.spyOn(myClass.prototype, "_methodA").mockReturnValue({});
const spyB = jest.spyOn(myClass.prototype, "_methodB").mockReturnValue({});
const obj = new myClass();
obj.main();
expect(spyA).toHaveBeenCalledTimes(1);
expect(spyB).toHaveBeenCalledTimes(1);
});
The other case using Db data is possible too:
it("Testing", () => {
const obj = new classA();
obj.main();
const spyA = jest.spyOn(DBClass.prototype, "getData").mockReturnValue({}); // DBClass could be a db class or a mock class
expect(spyA).toHaveBeenCalledTimes(1);
});
Answer from lissettdm on Stack OverflowJest spyOn not working for ES6 class methods?
Jest spyOn() calls the actual function instead of the mocked
Jest spy not working while testing a function within a function
spyOn not working as expected
I'm genuinely at my wit's end and need a bit of help with this. I'm attempting to write unit tests for an authentication service I'm developing in NestJS but am unable to mock external dependencies (e.g., 'firebase/auth' or even something like 'axios,' just for the hell of it). The Jest documentation says to just do something like this:
jest.mock('axios')
axios.get.mockResolvedValue('blah')
const result = await axios.get('blah')
expect(axios.get)toHaveBeenCalled()
But that simply does not work, and, believe me, I've attempted pretty much all variations of Jest's mocking mechanism. All I want to do, for instance, is assert that a function exported by an external dependency has been invoked. I recall this being something insanely easy to accomplish, but I've literally spent about six hours trying to figure it out now. Are any of you able to get the above example working within a TypeScript NestJS app--especially without there being griping about types and the like. I just want to do this simple thing. I should mention that the Axios example is important only insofar as it allows me to verify that I can mock an external dependency, which is a basic thing I presently am unable to accomplish.
Found great help from the answer here: Jest spyOn function called
This was the important step I was missing:
const instance = wrapper.instance()
const spy = jest.spyOn(instance, 'yearOnChange')
Updated working test with 2 working expects.
it('yearOnChange method is called', function() {
const instance = wrapper.instance(); // <-- Needed to do this here
const spy = jest.spyOn(instance, 'yearOnChange'); // <-- Then use instance here
wrapper.instance().forceUpdate();
const event = {
target: {
value: '1999'
}
};
wrapper.instance().yearOnChange(event);
wrapper.simulate('change', event);
const result = wrapper.state('year');
console.log('result', result); // result = 1999
expect(result).toEqual('1999');
expect(spy).toHaveBeenCalled();
});
You are spying and calling yearOnChange manually.
Try not calling wrapper.instance().yearOnChange(event);
Call the wrapper.instance().onChange event, or like you did, run the simulate('change') will be enough.
You could also try VehiclePicker.prototype.yearOnChange = jest.fn()
expect(VehiclePicker.prototype.yearOnChange).toBeCalled();
Hi all, I'm trying to unit test my code.
Jest outputs that the last 2 lines userService.findOne is not called although the result of the function is as expected auth.service.validateUserLogin... I'm not sure why is this so.
would appreciate any help thanks!
export class AuthService {
constructor(
private userService: UserService,
) {}
async validateUserLogin(username: string, pass: string): Promise<any> {
const user = await this.userService.findUserPasswordByUsername(username);
if (user) {
const isMatch = await bcrypt.compare(pass, user.password);
if (isMatch) {
return await this.userService.findOne(user.id);
}
throw new UnauthorizedException('Incorrect password');
}
return null;
}
}
describe('AuthService', () => {
let authService: AuthService;
let userService: UserService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
AuthService,
{
provide: UserService,
useValue: {
findUserPasswordByUsername: jest.fn().mockReturnValue({
id: 'AKJSSNSN8182020',
password: 'password',
}),
findOne: jest.fn().mockReturnValue({
id: 'AKJSSNSN8182020',
username: 'admin',
role: 'admin',
}),
},
}
],
}).compile();
authService = module.get<AuthService>(AuthService);
userService = module.get<UserService>(UserService);
});
afterEach(async () => {
jest.clearAllMocks();
});
it('should be defined', () => {
expect(authService).toBeDefined();
expect(userService).toBeDefined();
});
describe('validate user login', () => {
it('correct password should return a user object', () => {
bcrypt.compare = jest.fn(() => true);
expect(
authService.validateUserLogin('admin', 'password'),
).resolves.toEqual({
id: 'AKJSSNSN8182020',
username: 'admin',
role: 'admin',
});
const findUserPasswordByUsernameSpy = jest.spyOn(
userService,
'findUserPasswordByUsername',
);
expect(findUserPasswordByUsernameSpy).toBeCalledTimes(1);
expect(findUserPasswordByUsernameSpy).toBeCalledWith('admin');
const findOneSpy = jest.spyOn(userService, 'findOne');
expect(userService.findOne).toBeCalledTimes(1);
expect(userService.findOne).toBeCalledWith('AKJSSNSN8182020');
});
});
});