Mateusz Klimentowicz
Mateusz Klimentowicz

Reputation: 709

JEST: unit tests are successful although an unknown component is used

Why does the unit test not fail locally even though a component is used that does not exist but in bitbucket pipeline it does?

To demostrate the problem I have created a new nx workspace (Repository).

When running 'npx jest' locally, a console.error comes up that the component is not known but the test does not fail. On the other hand, the same command causes the opposite in the pipeline (Pipeline). It's a big problem for us because by having the unit tests fail only in the pipeline, we lose a lot of time to get them up and running again.

Upvotes: 0

Views: 1191

Answers (2)

moritzpflaum
moritzpflaum

Reputation: 729

As AliF50 correctly identified, your issue results from angular handling missing element types differently depending on some setup component. Monkey patching console.error is definitely a viable solution to avoid making this error locally. But the reason your build behaved differently in the bitbucket pipeline is something else. If you look at the log output of the pipeline step npm ci you can see one of the last log messages is:

npm WARN lifecycle [email protected]~postinstall: cannot run in wd [email protected] node ./decorate-angular-cli.js && ngcc --properties es2015 browser module main (wd=/opt/atlassian/pipelines/agent/build)

This stems from npm refusing to run postinstall scripts when running as root (which makes sense for most cases if you think about it). It tries to change the user which results in the problem you see about “cannot run in…”:

https://manpages.ubuntu.com/manpages/focal/en/man7/npm-scripts.7.html#user

If npm was invoked with root privileges, then it will change the uid to the user account or uid specified by the user config, which defaults to nobody. Set the unsafe-perm flag to run scripts with root privileges.

I think what happens is:

  • Your postinstall script is not executed
  • Ngcc is not called to precompile modules
  • Tests use JIT compilation for some reason (I’m not exactly sure why)
  • The “'not-existing-component' is not a known element”-warning becomes an error.
  • Pipeline fails.

Solution

As detailed in https://stackoverflow.com/a/47748545/1658032

You have two options:

  1. Adding --unsafe-perm
  2. Creating a user in the Dockerfile and switching to it

Upvotes: 2

AliF50
AliF50

Reputation: 18879

I think you're facing this issue: https://github.com/angular/angular/issues/36430 and this user has the exact same issue as you: https://github.com/angular/angular/issues/36430#issuecomment-611374846

Now why it fails on Bitbucket pipelines but not locally is strange.

What you can try to do is in test.ts add similar lines to the end of test.ts:

console.warn = function (message?: any, ...optionalParams: any[]): void {
  console.log({ message, optionalParams });
  fail('Test emitted a console warning!', message);
};
console.error = function (message?: any, ...optionalParams: any[]): void {
  console.log({ message, optionalParams });
  fail('Test emitted a console error!', message);
};

We are overriding the definition of console.error and console.warn to fail the test.

Then the unit test should fail with the is not a known element error.

Be careful, that now if your unit tests have a console.error or a console.warn, the unit tests will fail.

Upvotes: 1

Related Questions