Skip to content
This repository has been archived by the owner on Apr 3, 2023. It is now read-only.

Unable to test component with useKeycloak React Hook #198

Open
RMCampos opened this issue Oct 28, 2022 · 1 comment
Open

Unable to test component with useKeycloak React Hook #198

RMCampos opened this issue Oct 28, 2022 · 1 comment

Comments

@RMCampos
Copy link

Hello developers! I'm trying to get a React component tested, but I'm having this error: authClient has not been assigned to ReactKeycloakProvider. I think it's related to new versions of react-keycloak, based on some answers on SO. Any help is appreciated. Here's what I have:

App.tsx file

<ReactKeycloakProvider
    initOptions={initOptions}
    authClient={keycloak}
  >
  <BrowserRouter>
     // code here
  </BrowserRouter>
</ReactKeycloakProvider>

Header.tsx file:

const Header = () => {
  const { keycloak } = useKeycloak();
  return (
    {!keycloak?.authenticated && (
      <Button
        onClick={() => { keycloak?.login(); }}
        size="sm"
      >
        Login
      </Button>
      ... more code ...
    )}
  );
};
export default Header;

Header.test.tsx file:

import { render } from '@testing-library/react';
import React from 'react';
import renderer from 'react-test-renderer';
import Header from '../../components/BCHeader';
import createKeycloakStub from './MockKeycloak';

describe('the Header component', () => {
  const mockInitialized = false;

  jest.mock('@react-keycloak/web', () => {
    const originalModule = jest.requireActual('@react-keycloak/web');
    return {
      ...originalModule,
      useKeycloak: () => [
        createKeycloakStub,
        mockInitialized
      ]
    };
  });

  it('should have the correct title', () => {
    const { getByTestId } = render(<Header />);

    expect(getByTestId('header-name').textContent).toBe('BC Gov\'s\xA0NR Sample App');
  });

  it('should match the snapshot', () => {
    const tree = renderer
      .create(<Header />)
      .toJSON();
    expect(tree).toMatchSnapshot();
  });
});

MockKeycloak.tsx file:

import { KeycloakProfile, KeycloakPromiseCallback } from 'keycloak-js';

const userProfile: KeycloakProfile = {
  id: '1',
  username: 'test',
  email: 'test@testdomain.com',
  firstName: 'Test',
  lastName: 'User',
  enabled: true,
  emailVerified: false,
  totp: true,
  createdTimestamp: 123456789123
};

let authenticated: boolean = false;

const createKeycloakStub = () => ({
  init: jest.fn().mockResolvedValue(true),
  login() {
    authenticated = true;
  },
  logout() {
    authenticated = false;
  },
  register: jest.fn(),
  accountManagement: jest.fn(),
  createLoginUrl: jest.fn(),
  createLogoutUrl: jest.fn(),
  createRegisterUrl: jest.fn(),
  createAccountUrl: jest.fn(),
  isTokenExpired(minValidity?: number | undefined) {
    return false;
  },
  updateToken: jest.fn(),
  clearToken: jest.fn(),
  hasRealmRole(role: string) {
    return true;
  },
  hasResourceRole(role: string) {
    return true;
  },
  loadUserProfile() {
    return userProfile;
  },
  loadUserInfo: jest.fn()
});

export default createKeycloakStub;

PS: this code is based on two questions from Stackoverflow, but from older versions:

PS 2: I've tried with a ReactKeycloakProvider (based on the second link from SO) but without success, it seems the new version is asking for types that cannot be found.

Sorry for the long question. Thanks in advance fellows!

More info:

  • React: ^18.2.0
  • @react-keycloak/web: ^3.4.0
  • keycloak-js: ^19.0.3
  • jest: ^29.0.0
  • Operational System: GNU Linux Ubuntu 22.04
@RMCampos
Copy link
Author

RMCampos commented Nov 9, 2022

All right. I figured it out based on this SO question: https://stackoverflow.com/questions/65992356/how-to-get-a-keycloak-mock-to-work-with-jest.

Just implement the same way described at this link and should work.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant