I am testing my error boundaries to React and noticed in Codecov that there is a particular part of my Sentry function that hasn't been tested.
I have tried to use jest.mock("@sentry/browser") and mocking Sentry, however, can't seem to get the lines tested. The Sentry import is mocking correctly but not scope
.
Here is an example of my attempt at mocking.
import * as Sentry from "@sentry/browser"
const mock_scope = jest.fn(() => {
return { setExtras: null }
})
Sentry.withScope = jest.fn().mockImplementation(mock_scope)
The untested lines are this callback function being passed to Sentry.withScope
:
scope => {
scope.setExtras(errorInfo);
Sentry.captureException(error);
}
Since Sentry.withScope
has been mocked you can use mockFn.mock.calls
to retrieve the callback function passed to it.
Once you have retrieved the callback function, you can call it directly to test it.
Here is a slightly simplified working example:
import * as Sentry from '@sentry/browser';
jest.mock('@sentry/browser'); // <= auto-mock @sentry/browser
const componentDidCatch = (error, errorInfo) => {
Sentry.withScope(scope => {
scope.setExtras(errorInfo);
Sentry.captureException(error);
});
};
test('componentDidCatch', () => {
componentDidCatch('the error', 'the error info');
const callback = Sentry.withScope.mock.calls[0][0]; // <= get the callback passed to Sentry.withScope
const scope = { setExtras: jest.fn() };
callback(scope); // <= call the callback
expect(scope.setExtras).toHaveBeenCalledWith('the error info'); // Success!
expect(Sentry.captureException).toHaveBeenCalledWith('the error'); // Success!
});
Note that this line:
const callback = Sentry.withScope.mock.calls[0][0];
...is getting the first argument of the first call to Sentry.withScope
, which is the callback function.