milo
milo

Reputation: 477

Mocking node module in Detox test

Is it possible to mock a node_module using guide provided here: https://github.com/wix/Detox/blob/master/docs/Guide.Mocking.md

I was able to mock a regular file, but is it also possible for node modules? If so, how would I do that?

Upvotes: 4

Views: 931

Answers (2)

Overground
Overground

Reputation: 13

You can mock any package in your project by simply replacing the path to the target module with your mock file when building the application. The advantage of this approach is that you don't have to change your real code. For example, if you want to mock the codepush package, you would change your metro.config.js file:

// solution for Metro < 0.68
const defaultResolver = require('metro-resolver').resolve;

module.exports = {
  resolver: {
    resolveRequest: (context, moduleName, platform, realModuleName) => {
      if (process.env.DETOX_TEST === 'true' && moduleName === 'react-native-code-push') {
        return {
          filePath: `${__dirname}/src/Codepush.mock.js`,
          type: 'sourceFile'
        };
      }

      return defaultResolver(
        {
          ...context,
          resolveRequest: null
        },
        moduleName,
        platform,
        realModuleName,
      );
    }
  }
}

For more details, see this answer. Also see the metro documentation

Upvotes: 0

Daniel
Daniel

Reputation: 367

To mock a third party module with detox, you need to create some sort of a proxied module. Then you can create a mock-version of that file which detox then can pick up for testing.

In my case I wanted to mock expo-tracking-transparency.

  1. I created my proxy file expo-tracking-transparency.ts which just exports again what the package expo-tracking-transparency itself exports:
export * from 'expo-tracking-transparency';
  1. Next to this file (in the same folder) I created a mock-File expo-tracking-transparency.mock.ts which mocks the functions I need:
- src/helpers
       |__ expo-tracking-transparency.ts
       |__ expo-tracking-transparency.mock.ts
import { PermissionResponse, PermissionStatus } from 'expo-tracking-transparency';

const response: PermissionResponse = {
  status: PermissionStatus.DENIED,
  granted: false,
  expires: 'never',
  canAskAgain: true,
};

const requestTrackingPermissionsAsync = (): Promise<PermissionResponse> => Promise.resolve(response);

const getTrackingPermissionsAsync = (): Promise<PermissionResponse> => Promise.resolve(response);

export { requestTrackingPermissionsAsync, getTrackingPermissionsAsync };

  1. Now, to make the magic happen (=to make detox pick up the mock-file instead of the helper-file), you need to run metro with the --sourceExts-option where you set mock-extensions before your normal file extensions like so:
react-native start --sourceExts mock.ts,mock.js,js,json,ts,tsx

With Metro running start your detox tests and it should pickup your mock-files if they are present.

Upvotes: 0

Related Questions