Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest - when using spyOn function ensure the spied one is not called

From Jest notes: Note: By default, jest.spyOn also calls the spied method.

In my Angular component.

ngAfterViewInit(): void {
  this.offsetPopoverPosition();
}

In my spec:

it('ngAfterViewInit() method should call offsetPopoverPosition() method', () => {
    const mockListener = jest.spyOn(cmp, 'offsetPopoverPosition');
    const spy = mockListener.mockImplementation(() => {
      console.log('in the mock');
    });

    cmp.ngAfterViewInit();
    expect(spy).toHaveBeenCalled();
  });

Simple. Yet the original function is still being called. I checked Jest 23.x docs: https://jestjs.io/docs/en/23.x/jest-object#jestspyonobject-methodname https://jestjs.io/docs/en/23.x/mock-function-api#mockfnmockimplementationfn

And few examples on the internets but I can't prevent jest from calling the original offsetPopoverPosition() method.

Any ideas?

I am cross linking to Jest github issue which is for some reason closed without resolving it.

Jest spyOn() calls the actual function instead of the mocked

like image 387
codeepic Avatar asked Apr 25 '19 15:04

codeepic


People also ask

How do you use spyOn function in jest?

To spy on an exported function in jest, you need to import all named exports and provide that object to the jest. spyOn function. That would look like this: import * as moduleApi from '@module/api'; // Somewhere in your test case or test suite jest.

What is the difference between spyOn and mock in jest?

jest. mock does this automatically for all functions in a module. jest. spyOn does the same thing but allows restoring the original function.

Does jest spyOn mock?

Before every function is run in the file, jest will mock , and after every , jest will restore the function to its original implementation. Using the hooks for setup ensures that every test is fresh and independent of each other.


1 Answers

From my experience, the issue is you're resetting the original mock's intent. When you create a spy, it has its own implementation, by overriding it with mockImplementation, I've experienced the scenario you are describing - instead, try this:

cmp.offsetPopoverPosition = jest.fn().mockImplementation(() => {
      console.log('in the mock');
    });
const mockListener = jest.spyOn(cmp, 'offsetPopoverPosition');
// ... do work
expect(mockListener).toHaveBeenCalled[Times,With]()

also this assumes that cmp is an instance of the component and not just it's definition reference

edit: please note that mocking out a messaged function inside of the component you are testing is a misguided approach to unit testing. Instead of testing communication to the sameComponent.method - test any messaging that chained method uses outside of the component being tested - With the brief question content, please ignore the testing approach advice I've given if its reading tea leaves and not relevant to your unit test design(s)

like image 173
Brandt Solovij Avatar answered Sep 25 '22 02:09

Brandt Solovij