Search code examples
reactjsunit-testingjestjsnext.jsrecaptcha

How to Account for Google reCaptcha in Jest Unit Test with NextJS API


I've setup a simple API endpoint with NextJS and want to be able to implement some unit tests for it.

The endpoint uses Google recaptcha to protect the site (and the site owner's email) from bot spamming.

The endpoint is seemingly working as expected however I feel like the method I have used in order to enable me to unit test it is somewhat hacky.

The basic gist of my solution is to simply check if the NODE_ENV is set to test and return a generic success JSON if it is:

  if (process.env.NODE_ENV === "test")
    return {
      success: true,
      challenge_ts: new Date().getTime(),
      error_codes: [],
      hostname: "localhost",
    };

If possible I would prefer to not ship the app with this code in the endpoint's module file as it just doesn't sit right with me.

The issue is that removing this code obviously means my tests all fail as they will return a status of 422 due to the lack of a response token from the Google ReCaptcha API.

I am using the react-google-recaptcha NPM package to implement ReCaptcha and have setup my jest config to use the .env.test files when running tests.

This allows me to use the suggested keys from Google's docs without any need for changing my config etc.

The issue I am facing is an inability to get the response token from the frontend implementation of ReCaptcha to then pass on to the NextJS API endpoint.

I have tried to use render and createRef mimicking my actual frontend implementation but within Jest to no avail.

Does anyone have a better solution to that which I have currently implemented?

Thanks in advance.

Love.


Solution

  • in addition to @Saurabh's answer, make sure you put this code snippet to the jest.setup.js file.
    I've also slightly changed the implementation:

    jest.mock('react-google-recaptcha', () => {
      const RecaptchaV2 = React.forwardRef((props, ref) => {
        React.useImperativeHandle(ref, () => ({
          reset: jest.fn(),
          execute: jest.fn(),
          executeAsync: jest.fn(() => 'token'),
        }));
        return <input ref={ref} type="checkbox" data-testid="mock-v2-captcha-element" {...props} />;
      });
    
      return RecaptchaV2;
    });