Search code examples
angularunit-testingjestjsapollo-angular

Angular 14 Upgrade w/ Jest 28 and Nx Having Issues with Jest Tests "Cannot find module 'apollo-angular'"


I have a very peculiar issue that I've been working on for quite some time. I am in the process of upgrading our main frontend app from Angular 12 to Angular 14. All the migrations were successful. The app builds and runs just fine. However, the tests are failing due to being unable to find the apollo-angular module. We use apollo-angular for making GQL requests to our backend services. The app makes the requests just fine. However, when I try to run my unit tests in the project, they always fail because they cannot find the apollo-angular module.

Error: enter image description here

Here is my current setup. Please let me know if I am missing any useful files and I will add them.

./jest.preset.ts

const nxPreset = require('@nrwl/jest/preset').default;

module.exports = {
  ...nxPreset,
};

./jest.config.ts

const { getJestProjects } = require('@nrwl/jest');

export default {
  projects: getJestProjects(),
};

./libs/shared/ui-components/jest.config.ts

import { pathsToModuleNameMapper } from 'ts-jest';
const { paths } = require('../../../tsconfig.base.json').compilerOptions;

export default {
  displayName: 'ui-components',
  preset: 'jest-preset-angular',
  setupFilesAfterEnv: ['../../../jest-setup.ts'],
  moduleNameMapper: pathsToModuleNameMapper(paths, {
    prefix: '<rootDir>/../../..',
  }),
  globals: {
    'ts-jest': {
      tsconfig: '<rootDir>/tsconfig.spec.json',
    },
  },
  transform: {
    '^.+.(ts|mjs|js|html)$': 'jest-preset-angular',
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
};

Any help would be greatly appreciated. I've been spinning my wheels on this for far too long.

Cheers, Nate


Solution

  • A solution has appeared! After a ton of research, I found that adding the following resolver to my jest.config.ts allowed the tests to execute successfully.

    /* eslint-disable */
    import { pathsToModuleNameMapper } from 'ts-jest';
    const { paths } = require('../../../tsconfig.base.json').compilerOptions;
    
    export default {
      displayName: 'shared-data-access-auth',
      preset: 'jest-preset-angular',
      setupFilesAfterEnv: ['../../../jest-setup.ts'],
      moduleNameMapper: pathsToModuleNameMapper(paths, {
        prefix: '<rootDir>/../../..',
      }),
      globals: {
        'ts-jest': {
          tsconfig: '<rootDir>/tsconfig.spec.json',
        },
      },
      transform: {
        '^.+.(ts|mjs|js|html)$': 'jest-preset-angular',
      },
      transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
      moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
      resolver: 'jest-preset-angular/build/resolvers/ng-jest-resolver.js',
    };
    

    The key factors of this fix were the transformIgnorePatterns of ['node_modules/(?!.*\\.mjs$)'], and the resolver of 'jest-preset-angular/build/resolvers/ng-jest-resolver.js',

    Hope this helps someone else!