Skip to content

test(integrations): Add unit tests for CaptureConsole #4733

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 6 commits into from
Mar 22, 2022

Conversation

lforst
Copy link
Member

@lforst lforst commented Mar 18, 2022

This adds some unit tests for the captureconsole integration.

Related to #4506
Ref: https://getsentry.atlassian.net/browse/WEB-636

@github-actions
Copy link
Contributor

github-actions bot commented Mar 18, 2022

size-limit report

Path Base Size (ebc9da5) Current Size Change
@sentry/browser - ES5 CDN Bundle (gzipped + minified) 19.49 KB 19.49 KB +0.01% 🔺
@sentry/browser - ES5 CDN Bundle (minified) 62.17 KB 62.17 KB 0%
@sentry/browser - ES6 CDN Bundle (gzipped + minified) 18.11 KB 18.11 KB 0%
@sentry/browser - ES6 CDN Bundle (minified) 55.5 KB 55.5 KB 0%
@sentry/browser - Webpack (gzipped + minified) 22.6 KB 22.6 KB 0%
@sentry/browser - Webpack (minified) 79.21 KB 79.21 KB 0%
@sentry/react - Webpack (gzipped + minified) 22.63 KB 22.63 KB 0%
@sentry/nextjs Client - Webpack (gzipped + minified) 47.6 KB 47.6 KB 0%
@sentry/browser + @sentry/tracing - ES5 CDN Bundle (gzipped + minified) 25.36 KB 25.36 KB 0%
@sentry/browser + @sentry/tracing - ES6 CDN Bundle (gzipped + minified) 23.72 KB 23.72 KB 0%

@lforst lforst force-pushed the lforst-captureconsole-unit-tests branch from ee0d41f to 9ab350e Compare March 18, 2022 10:47
@AbhiPrasad AbhiPrasad changed the title test(integrations): Add unit tests for caputureconsole test(integrations): Add unit tests for CaptureConsole integration Mar 18, 2022
@AbhiPrasad AbhiPrasad changed the title test(integrations): Add unit tests for CaptureConsole integration test(integrations): Add unit tests for CaptureConsole Mar 18, 2022
Copy link
Member

@Lms24 Lms24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congrats on this first PR! These tests look good to me. Learnt a ton about this integration when reading the tests. While these changes LGTM, I think someone who knows more about the integration should approve it, just to be extra sure about their correctness.

I was just wondering if we should perhaps test for correct behaviour when users pass an empty array for the log levels to the CaptureConsole ctor? Not sure if this adds value but it might cover a rare edge case.

@lforst
Copy link
Member Author

lforst commented Mar 18, 2022

@Lms24 Thanks for taking a look!

we should perhaps test for correct behaviour when users pass an empty array for the log levels to the CaptureConsole ctor

We have this test https://github.com/getsentry/sentry-javascript/pull/4733/files#diff-ff37e9990ef1d25deeae200c9e7e5be462f00528070535f97e9b1a2075690c8eR47-R65 but you're probably right, we should add at least one that tests the happy path for no constructor args.

I added some in: 5c24751

@Lms24
Copy link
Member

Lms24 commented Mar 18, 2022

We have this test #4733 (files) but you're probably right, we should add at least one that tests the happy path for no constructor args.

I added some in: 5c24751

Thanks, I saw the test - great to have this one for sure. What I was initially thinking about though, was having an additional test covering an edge case where you pass something like this to the constructor: new CaptureConsole({ levels: [] }); What do you think?

@lforst
Copy link
Member Author

lforst commented Mar 18, 2022

What I was initially thinking about though, was having an additional test covering an edge case where you pass something like this to the constructor: new CaptureConsole({ levels: [] }); What do you think?

Ohhh right. Yeah agree. I'll add another one 😄

Copy link
Member

@AbhiPrasad AbhiPrasad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will get to the rest later

const captureConsoleIntegration = new CaptureConsole({ levels: ['log', 'warn'] });
captureConsoleIntegration.setupOnce(
() => undefined,
() => getMockHubWithIntegration(captureConsoleIntegration) as any,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid the any cast here?

What do you think about extracting the following into a helper instead just having the helper for mocking the hub? I think it works fine in the getMockHubWithIntegration(null) case.

    captureConsoleIntegration.setupOnce(
      () => undefined,
      () => getMockHubWithIntegration(null) as any, // simulate not having the integration registered
    );

Copy link
Member Author

@lforst lforst Mar 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH I don't like extracting the function we intend to test into a helper. We don't gain anything from it and the tests just become more convoluted.

As for the any cast: I kinda struggled with that one. The Hub interface is huge and I didn't feel like mocking it out in its entirety when we only need a small subset. Typescript also doesn't appreciate us casting it to Hub because a bunch of methods are missing. Do you have an idea on how to do this properly?

I personally really like the jest-mock-extended library for type-safe mocks in unit tests. It works really well, however idk if we should introduce a dependency for this. I initially discovered this library because the prisma orm recommends it for their unit tests. Let me know what you think!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for the any cast: I kinda struggled with that one. The Hub interface is huge and I didn't feel like mocking it out in its entirety when we only need a small subset. Typescript also doesn't appreciate us casting it to Hub because a bunch of methods are missing. Do you have an idea on how to do this properly?

Yeah fair, let's leave the any cast.

I would be open to adding jest-mock-extended, but let's stay away from it for now since we probably need to figure out how we roll it out across all of our tests.

expect(global.console.assert).not.toBe(originalConsole.assert);

// any other fields should not have been patched
expect(global.console.trace).toBe(originalConsole.trace);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trace should probably be patched, see #4599

maybe we take that on as a quick win after this? There is also #4532 to keep in mind.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah let's take this on afterwards! I'm gonna leave this test like this for now because we want to test the current behaviour. The PR that resolves #4599 should also adjust this test.

Object.assign(global.console, originalConsole);
});

it('should respect user-provided console levels', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't know if it can respect :P

Suggested change
it('should respect user-provided console levels', () => {
it('should patch user-configured console levels', () => {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I updated the test name: 179d8d8

global.console.assert(1 + 1 === 3);

expect(mockScope.setExtra).toHaveBeenLastCalledWith('arguments', []);
expect(mockHub.captureMessage).toHaveBeenCalledWith('Assertion failed: console.assert');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto for the others

Suggested change
expect(mockHub.captureMessage).toHaveBeenCalledWith('Assertion failed: console.assert');
expect(mockHub.captureMessage).toHaveBeenCalledTimes(1);
expect(mockHub.captureMessage).toHaveBeenCalledWith('Assertion failed: console.assert');

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. This can't hurt. I added additional checks here: af223e9

const captureConsoleIntegration = new CaptureConsole({ levels: ['log', 'warn'] });
captureConsoleIntegration.setupOnce(
() => undefined,
() => getMockHubWithIntegration(captureConsoleIntegration) as any,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for the any cast: I kinda struggled with that one. The Hub interface is huge and I didn't feel like mocking it out in its entirety when we only need a small subset. Typescript also doesn't appreciate us casting it to Hub because a bunch of methods are missing. Do you have an idea on how to do this properly?

Yeah fair, let's leave the any cast.

I would be open to adding jest-mock-extended, but let's stay away from it for now since we probably need to figure out how we roll it out across all of our tests.

@lforst lforst merged commit a929462 into master Mar 22, 2022
@lforst lforst deleted the lforst-captureconsole-unit-tests branch March 22, 2022 11:55
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants