React - Jest test failing - TestingLibraryElementError: Unable to find an element with the text

740 Views Asked by At

I've a jest test that is failing on addition of a new component to the page. The test is about showing of an error alert once error occurs. Code works in local environment but fails during commit.

Error Text:

TestingLibraryElementError: Unable to find an element with the text: Student is unable to perform register/unregister activities.. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Test:

jest.mock('react-query', () => ({
      ...jest.requireActual('react-query'),
      useMutation: jest.fn((_key, cb) => {
        cb();
    
        return { data: null };
 })
 }));
    
 const useMutation = useMutationHook as ReturnType<typeof jest.fn>;
    
    describe('StatusAlert', () => {
      beforeEach(() => {
        useMutation.mockReturnValue({});
      });
    
      afterEach(() => {
        jest.restoreAllMocks();
      });

    it('should show error', () => {
        useMutation.mockReturnValueOnce({
          isError: true
        });
    
        const { getByText } = render(
          <StudentRegister
            students={[studentStub, studentStub]}
            onSuccess={jest.fn()}
          />
        );
        expect(getByText(ErrorDict.ErrorRequest)).toBeInTheDocument();
      });

StudentRegister:

Adding this component is causing the above mentioned error:

interface Props {
      selectedStudents: Array<Student>;
      onSuccessCallback: () => void;
    }
    
export const StudentSelectionBar: FC<Props> = ({
  selectedStudents,
  onSuccessCallback
}) => {
  const [isOpenDropCourseModal, setisOpenDropCourseModal] = 
      useState(false);
  const [studentIds, setStudentIds] = useState<string[]>([]);
  useEffect(() => {
        setStudentIds(selectedStudents.map((student) => 
      student.id));
  }, [selectedStudents]);

  const onToggleOpenDropCourseModal = useCallback(() => {
    setisOpenDropCourseModal(
      (state) => !state
    );
  }, []);

  
  const {
    isError: isDropCourseError,
    isSuccess: isDropCourseSuccess,
    isLoading: isDropCourseLoading,
    mutateAsync: DropCourseMutation,
    error: DropCourseError
  } = useMutation<void, ApiError>(
    () => dropCourse(selectedStudents.map((student) => 
       student.id)),
    {
      onSuccess() {
        onToggleOpenDropCourseModal();
        onSuccess();
      }
    }
  );

  return (
    <>
      <StatusAlert
        isError={isDropCourseError}
        isSuccess={isDropCourseSuccess}
        errorMessage={
          dropCourseError?.errorMessage || 
              ErrorMessages.FailedPostRequest
        }
        successMessage="Students successfully dropped from 
         course"
      />
      <StatusAlert
        isError={registerMutation.isError}
        isSuccess={registerMutation.isSuccess}
        errorMessage={
          registerMutation.error?.errorMessage ||
          ErrorDict.ErrorRequest
        }
        successMessage="Students successfully registered"
      />
      <StatusAlert
        isError={isError}
        isSuccess={isSuccess}
        errorMessage={
           error?.errorMessage ||
           ErrorDict.ErrorRequest
        }
        successMessage="Students successfully unregistered"
      />
      <Permissions scope={[DropCourseUsers]}>
        <LoadingButton
          color="error"
          variant="contained"
          onClick={onToggleDropCourseUserModal}
          className={styles['action-button']}
          loading={isDropCourseLoading}
          loadingPosition="center"
          disabled={registerMutation.isLoading || isLoading}
        >         
          drop Course
        </LoadingButton>
      </Permissions>
      <DropCourseModal
        isOpen={isOpenDropCourseModal}
        onCloseModal={onToggleOpenDropCourseModal}
        onArchiveUsers={DropCourseMutation}
        users={studentIds}
      />
    </>
  );
};

Update:

I've noticed that removing useEffect() hook from the component, makes it render correctly in the test. Its function is to update the state variable holding studentIds on every selection on the list.

Is there a way to mock following useEffect hook with dependency in the test?

const [studentIds, setStudentIds] = useState<string[]>([]);
useEffect(() => {
      setStudentIds(selectedStudents.map((student) => student.id));
}, [selectedStudents]);
0

There are 0 best solutions below