question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add types to "__mocks__/BackHandler.js"

See original GitHub issue

Description

Today when we need to mock the Android back press, the only way I found is using the Libraries/Utilities/__mocks__/BackHandler.js file, and then:

jest.mock(
    'react-native/Libraries/Utilities/BackHandler',
    () => require('react-native/Libraries/Utilities/__mocks__/BackHandler'),
);

However, when using TypeScript we get an error:

// my-test.spec.tsx

import { BackHandler } from 'react-native';

describe('My test', () => {
  it('BackHandler', () => {
      BackHandler.mockPressBack();
      // Error: Property 'mockPressBack' does not exist on type 'BackHandlerStatic'.ts(2339)
  });
});

My workaround is to create a react-native.d.ts file with:

import 'react-native';

declare module 'react-native' {
  interface BackHandlerStatic {
    mockPressBack(): void;
  }
}

Version

0.68.2

Output of npx react-native info

System: OS: macOS 12.3.1 CPU: (8) arm64 Apple M1 Memory: 173.70 MB / 8.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 16.16.0 - ~/.nvm/versions/node/v16.16.0/bin/node Yarn: 1.22.19 - ~/.nvm/versions/node/v16.16.0/bin/yarn npm: 8.11.0 - ~/.nvm/versions/node/v16.16.0/bin/npm Watchman: 2022.05.16.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.11.2 - /Users/douglas.junior/.rbenv/shims/pod SDKs: iOS SDK: Platforms: DriverKit 21.4, iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5 Android SDK: Not Found IDEs: Android Studio: 2021.1 AI-211.7628.21.2111.8139111 Xcode: 13.3.1/13E500a - /usr/bin/xcodebuild Languages: Java: 11.0.12 - /opt/homebrew/opt/openjdk@11/bin/javac npmPackages: @react-native-community/cli: Not Found react: 17.0.2 => 17.0.2 react-native: 0.68.2 => 0.68.2 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Steps to reproduce

Just create a new React Native project with TypeScript and try to create a mock for BackHandler.

Snack, code example, screenshot, or link to a repository

N/A

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
SparshaSahacommented, Aug 18, 2022

I see, so: You are basically trying to test what happens in your code when backHandler’s backPress is invoked right? You don’t really need BackHandler’s implementation for that. You can very easily mock BackHandler, like this I think:

const handleDismissMock = jest.fn();
const mockBackHandler = {
 addEventListener: jest.fn(),
 mockBackPress: jest.fn().mockImplementation(() => {
handleDismissMock();
});
}

jest.mock("react-native", () => {
 return {
xyz...,
BackHandler: mockBackHandler
}
})

What this essentially does is that we create a mock of BackHandler which, when mockBackPress is called, invokes the handleDismiss method.

this should work fine with your code @douglasjunior . Let me know if this helps

Make sure you pass handleDismissMock as handleDismiss when rendering Modal

1reaction
douglasjuniorcommented, Aug 16, 2022

I’m creating a Modal component that need to close when the “back button” was pressed.

So, in my tests I do:

import React from 'react';
import { StatusBar } from 'react-native';

import { render, act } from '@testing-library/react-native';
// @ts-ignore
import BackHandler from 'react-native/Libraries/Utilities/__mocks__/BackHandler';

import Modal from '.';

jest.mock('react-native/Libraries/Utilities/Platform', () => {
  const Platform = jest.requireActual(
    'react-native/Libraries/Utilities/Platform',
  );
  Platform.OS = 'android';
  return Platform;
});

const ANIMATION_DURATION = 10;

describe('Modal on Android', () => {
  it('dismissible', () => {
    const handleDismiss = jest.fn();
    const handleDismissEnd = jest.fn();

    render(
      <Modal
        visible
        onDismiss={handleDismiss}
        onDismissEnd={handleDismissEnd}
        animationDuration={ANIMATION_DURATION}
      />,
    );

    act(() => {
      BackHandler.mockPressBack();
    });

    expect(handleDismiss).toBeCalled();

    setTimeout(() => {
      expect(handleDismissEnd).toBeCalled();
    }, ANIMATION_DURATION);
  });
});

Inside Modal I have:

  useEffect(() => {
    if (visible) {
      const handleBack = () => {
        if (dismissible) {
          onDismiss?.();
        }
        return true;
      };

      const listener = BackHandler.addEventListener('hardwareBackPress', handleBack);

      return () => {
        listener.remove();
      };
    }
    return undefined;
  }, [visible, dismissible, onDismiss]);

Everything is working, except for the BackHandler.mockPressBack() type.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to simulate the back button through enzyme or jest with ...
You just need to mock BackHandler component. ... To simulate hardwareBackPress I'd suggest few different ways: to mock addEventListener ...
Read more >
Mocking RN modules | React Made Native Easy
To do so, we need to mock a property in react-native, since NativeModules comes from 'react-native'. 1. create __mocks__/react-native.js 2. Add the following ......
Read more >
Testing React Native Apps - Jest
Snapshot Test​. Let's create a snapshot test for a small intro component with a few views and text components and some styles: Intro.js....
Read more >
Advanced testing in React Native with Jest: Mocking
Thankfully, jest supports various mocking styles out of the box. ... You can enable automocking by adding this line to your Jest config:...
Read more >
BackHandler - React Native
The Backhandler API detects hardware button presses for back navigation, lets you register event listeners for the system's back action, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found