0

I've create a very simple component which shows an image based on the os you are on (in my case iOS and Android)

import { UAParser } from "ua-parser-js";

export const DownloadApp = ({ appleStoreUrl, playStoreUrl }: DownloadAppProps): JSX.Element => {
  const parser = new UAParser();
  const os = parser.getOS();

return (<div className="flex h-12">
        {os.name === "iOS" && (
          <div>
            <a href={appleStoreUrl} title="Apple App Store">
              <AppleAppStore height="48" />
            </a>
          </div>
        )}

        {(os.name === "Android" || os.name === "Android[-x86]") && (
          <div className="shrink">
            <a href={playStoreUrl} title="Google Play Store">
              <GooglePlayStore height="48" />
            </a>
          </div>
        )}
</div>)}

This all works great when manually testing on devices but I'm trying to write some unit tests in react-testing-library and jest to check that the correct image is shown based on the OS response.

I've tried mocking the ua-parser-js library but I always need to instantiate the library to get the getOS() function of which I want to set a mockImplementation to return iOS and Android but it seems to totally ignore the mock and just calls the ua-parser-js package and returns undefined.

Tom Maton
  • 1,564
  • 3
  • 23
  • 41

1 Answers1

0

Rather than mocking ua-parser-js there is the option of mocking the userAgent getter with jest. With this approach you can then use whatever user agent you like to match your test scenario.

In your beforeEach:

const userAgentGetter = jest.spyOn(window.navigator, 'userAgent', 'get')
userAgentGetter.mockReturnValue('Mozilla/5.0 (Macintosh; Intel Mac OS X 13_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15')

In your afterEach:

jest.restoreAllMocks()
Kzrbill
  • 1,449
  • 2
  • 10
  • 10