vue.jsjestjsvuexvue-test-utilsvue-testing-library

mock store getters inside Global Guard does not work


I created a global guard that uses getters from store.

I am trying to mock some getters from store for testing purpose. The problem is that mocking

does not work.

// router/index.ts
export function beforeEach(to: any, from: any, next: any) {
  const isLoggedIn = store.getters.isLoggedIn();
  const isGuest = to.matched.some((record: any) => (record.meta.guest));
  if (isLoggedIn) { // isLoggedIn is always false
    if (isGuest) {
      next('/');
    }
  } 
  }
}
//router/index.spec.ts
describe('shoud test routing functionality', () => {
it('should redirect to / when isLoggedIn is true and IsGuest is true', () => {
    // given
    jest.mock('@/store', () => ({
      getters: {
        isLoggedIn: jest.fn().mockImplementation(
          () => true, // <----------- this value is always false
        ),
      },
    }));

     // even this one does not work
     //  jest.spyOn(getters, 'isLoggedIn').mockImplementation(() => 
     //  ()=> true);

    const to = {
      matched: [{ meta: { guest: true } }],
    };
    const next = jest.fn();

    // when
    beforeEach(to, undefined, next);

    // then
    expect(next).toHaveBeenCalledWith('/');
  });
})

I inspired from this example.


Solution

  • Thanks @EstusFlask comment, I solved the problem.

    The keyword is that jest.mock inside a test can't affect top-level imports.

    jest.mock('@/store', () => ({
      getters: {
        isLoggedIn: jest.fn(),
      // other methods should be declared here, otherwise an exception is thrown
        isSuperAdmin: jest.fn(),
        isAdmin: jest.fn(),
        isReadUser: jest.fn(),
      },
    }));
    
    describe('should test routing functionality', () => {
       it('should redirect to / when isLoggedIn is true and IsGuest is true', () => {
        // given
        store.getters.isLoggedIn.mockImplementation(() => () => false);
        const to = {
          matched: [{ meta: { guest: true } }],
        };
        const next = jest.fn();
    
        // when
        beforeEach(to, undefined, next);
    
        // then
        expect(next).toHaveBeenCalledWith('/');
      });
    })