I am trying to mock the init method provided by sentry-expo
and so far, this is what I have come up with:
setupFilesAfterEnv.ts
import '@testing-library/jest-native/extend-expect';
import * as Sentry from 'sentry-expo';
import sentryTestkitSuite from 'sentry-testkit';
const DUMMY_DSN = 'https://acacaeaccacacacabcaacdacdacadaca@sentry.io/000001';
const { sentryTransport } = sentryTestkitSuite();
// https://stackoverflow.com/questions/44649699/service-mocked-with-jest-causes-the-module-factory-of-jest-mock-is-not-allowe
// Cannot use the imported module as a value directly
const mockSentryTransport = sentryTransport as jest.Mocked<
typeof sentryTransport
>;
jest.mock('sentry-expo', () => ({
...jest.requireActual('sentry-expo'),
init: (options?: Sentry.SentryExpoNativeOptions) => ({
...options,
transport: mockSentryTransport,
}),
}));
beforeAll(() =>
Sentry.init({
dsn: DUMMY_DSN,
release: 'test',
tracesSampleRate: 1,
beforeSend(event) {
return {
...event,
extra: { os: 'mac-os' },
};
},
}),
);
beforeEach(() => {
sentryTestkitSuite().testkit.reset();
});
All the test cases which have used Sentry to capture exceptions successfully pass.
Now, I have created a file for adding standard crash-reporting utilities:
crash-reporting.ts
import * as Sentry from 'sentry-expo';
import { getEnvironmentConfig } from '@utils/environment/environment';
const routingInstrumentation =
new Sentry.Native.ReactNavigationInstrumentation();
export const initialiseCrashReporting = () => {
return Sentry.init({
dsn: getEnvironmentConfig()?.sentryDSN,
// Enable it only when you install the Expo development build on your device/simulator
// If you enable it while running the app in Expo Go, native dependencies will not work as expected such as Sentry
enableInExpoDevelopment: __DEV__,
debug: __DEV__, // If `true`, Sentry will try to print out useful debugging information if something goes wrong with sending the event. Set it to `false` in production,
environment: getEnvironmentConfig()?.appEnv ?? 'development',
tracesSampleRate: __DEV__ ? 1 : 0.2,
integrations: [
new Sentry.Native.ReactNativeTracing({
tracingOrigins: ['localhost', /^\//],
routingInstrumentation,
}),
],
});
};
export const { wrap: sentryWrap } = Sentry.Native;
I am trying to test the above crash-reporting
module like so:
crash-reporting.test.ts
import * as Sentry from 'sentry-expo';
import { initialiseCrashReporting } from './crash-reporting';
jest.mock('sentry-expo', () => {
const originalModule = jest.requireActual('sentry-expo');
return {
...originalModule,
init: jest.fn(),
};
});
describe('Crash Reporting Test Suite', () => {
it('should initialise sentry', () => {
const initSpy = jest.spyOn(Sentry, 'init');
initialiseCrashReporting();
expect(initSpy).toHaveBeenCalled();
});
});
Even though initialiseCrashReporting
gets called, spyOn
never catches the event where init
gets called.
I realised that the globally mocked sentry-expo
never gets overridden with the one in the crash-reporting.test.ts
file.
I have 2 below-given questions related to this problem:
- How can I override the globally mocked modules? Or how can I be assured that by calling
initialiseCrashReporting
, I am initialising sentry? - Can we override global
beforeall
for specific test cases?
Thanks in anticipation!