#path not resolving when using Jest - jestjs

import { Utils } from '#domain/Utils'
import '#testing-library/jest-dom'
import useHasAccess from './useHasAccess'
describe('tests', () => {
it('should have access', () => {
const isHasAccess= useHasAccess()
const isAdmin = isHasAccess(Utils.Identity.Admin)
expect(isAdmin).toBe(true);
})
})
When running this simple test, I get: Cannot find module '#domain/Utils'
I tried putting the relative path, but I get the same error, but coming from a different file referenced by the imports, so I am wondering if there's a way for Jest to recognize the path settings set by Typescript. ESLint seems to recognize the path, so I am thinking something prevents Jest from finding the path.
"paths": {
"#domain/*": [
"./src/domain/*"
]
},
I found this inside my tsconfig, but there's no place to put it inside the jest configs:
module.exports = {
collectCoverage: true,
collectCoverageFrom: ['src/**/*.{js,jsx}'],
coverageDirectory: 'coverage',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/custom.setup.js'],
}

Related

Only 1 function is not being successfully mocked, the rest are

Apologies if the title isn't clear enough, I wasn't sure how to phrase it.
I've got an Nx monorepository with 2 applications:
backend (apps): An Express application
queries (libs): A library that contains queries to perform different db operations in mssql
I'm writing some tests for backend and for that, I want to be able to mock the functions that queries exports, as I don't want to be performing any operations in the database.
To mock queries I've done the following:
Firstly I've created a mocks folder: libs/queries/__mocks__/index.ts where I'm exporting all the mocked functions.
Secondly, in my test file I've writteng jest.mock('#mp/queries'), where #mp/queries is the library (uses TS Path mapping)
In my queries library I export the following function:
export const saveDocumentToDatabase = async (data: any, userId: number) => {
// Code to save doc in database
}
And in queries/__mocks__/index.ts I've got something very similar:
export const saveDocumentToDatabase = async (data: any, userId: number) => {
return;
}
This function works as expected. I've had no problems with this mocked function.
Then I've got another similar function:
export const getPermissionsFromId = async (permissionsId: number): Promise<any> => {
// Code to get permissions
}
And in my libs/queries/__mocks__/index.ts I've got:
export const getPermissionsFromId = async (permissionsId: number) => {
return { canLogin: true };
}
And this mocked function doesn't work. In my backend I've got a controller that makes use of getPermissionsFromId, and it always returns undefined.
I've got no idea why two mocked functions in the same file wouldn't behave the same. Has anyone got any ideas about what might be going wrong?
// jest.config.ts (apps/backend)
/* eslint-disable */
export default {
displayName: 'backend',
preset: '../../jest.preset.js',
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json'
}
},
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': 'ts-jest'
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/apps/backend'
};
// jest.config.ts (libs/queries)
/* eslint-disable */
export default {
displayName: 'queries',
preset: '../../jest.preset.js',
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json'
}
},
testEnvironment: 'node',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest'
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/libs/queries'
};
// jest.preset.ts
const nxPreset = require('#nrwl/jest/preset').default;
module.exports = { ...nxPreset };

Unable to get jest to load a module (pdf.js) in a component test

I am building tests using jest that makes use of the pdf.js node library, but keep getting the following error due to jest not picking up the library properly
TypeError: Cannot set property 'workerSrc' of undefined
Here is pdfParser.js:
import * as pdfJs from 'pdfjs-dist/legacy/build/pdf'
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'
pdfJs.GlobalWorkerOptions.workerSrc = pdfjsWorker
export const readPdf = async theFile => {
... (*it doesn't even get this far)
}
Here is my test (pdfParser.test.js):
import { readPdf } from '../../../../src/utils/pdfParser.js'
describe('PDF Parser', () => {
it('returns error when no file submitted', () => {
expect(1).toEqual(1)
})
})
I've tried setting the following in package.json
"jest": {
"moduleNameMapper": {
"pdfjs-dist": "<rootDir>/node_modules/pdfjs-dist/legacy/build/pdf.js"
},
"moduleDirectories": [
".",
"src",
"src/util",
"node_modules"
]
What am I doing wrong?

How can I ignore "-!svg-react-loader!./path/to/my.svg" when testing with Jest without bundling everything with webpack

We're using svg-react-loader for some of the SVG files in our application. We're trying to setup jest to run with a babel-jest and the following .babelrc:
{
"presets": [
"es2015",
"react"
],
"plugins": [
"transform-decorators-legacy",
"transform-class-properties",
"transform-object-rest-spread"
]
}
The following test fails:
/* global it, document */
import React from 'react'
import ReactDOM from 'react-dom'
import Comp from './Icon'
it('renders without crashing', () => {
const div = document.createElement('div')
ReactDOM.render(<Comp><div /></Comp>, div)
})
With error:
Cannot find module '-!svg-react-loader!../../assets/grid.svg' from 'Icon.js'
How could I ignore imports that start with like import grid from '-!svg-react-loader!../../assets/grid.svg' in jest?
The way I solved this was by adding a jest mock for any import that contains -!svg-react-loader! at the beginning of the module.
"moduleNameMapper": {
"^-!svg-react-loader.*$": "<rootDir>/config/jest/svgImportMock.js"
}
Where svgImportMock.js is:
'use strict';
module.exports = 'div';
It's not ideal, because the file could simple not exists, but the assumption is that we see the missing module when bundling with webpack.
I resolved this by installing jest-svg-transformer, then adding this config:
{
"jest": {
"transform": {
"^.+\\.svg$": "jest-svg-transformer"
}
}
}
I was able to solve this by correctly handling static assets in Jest (https://jestjs.io/docs/en/webpack#handling-static-assets):
// package.json
{
"jest": {
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
}
}
}
// __mocks__/styleMock.js
module.exports = {};
// __mocks__/fileMock.js
module.exports = 'test-file-stub';

Jest Testing with require modules: ejs-loader

I am playing with the idea of having large static html bundles just loaded into a react component vice typing them all out in jsx. I am currently just experimenting with ejs-loader and html-react-parser to evaluate the feasibility of this. Everything actually renders fine but I cannot get any tests to work with jest for this.
I receive: Cannot find module ejs-loader!./AboutPage.view.ejs from AboutPage.js errors and I am unsure of what to do.
I am currently just working off of react-slingshot as my base for experimenting with this.
The repo for the project is here
The component itself is simple:
import React from 'react';
import Parser from 'html-react-parser';
import '../styles/about-page.css';
const view = require('ejs-loader!./AboutPage.view.ejs')();
// Since this component is simple and static, there's no parent container for it.
const AboutPage = () => {
return (
<div>
{Parser(view)}
</div>
);
};
export default AboutPage;
And the test is:
import React from 'react';
import {shallow} from 'enzyme';
import AboutPage from './AboutPage';
describe('<AboutPage />', () => {
it('should have a header called \'About\'', () => {
const wrapper = shallow(<AboutPage />);
const actual = component.find('h2').text();
const expected = 'About';
expect(actual).toEqual(expected);
});
});
I have read through the docs and similar questions like this. I attempted to use a custom transformer, but I may be misunderstanding something as it doesn't appear to be even called.
Package.json
"jest": {
"moduleNameMapper": {
"\\.(css|scss)$": "identity-obj-proxy",
"^.+\\.(gif|ttf|eot|svg|woff|woff2|ico)$": "<rootDir>/tools/fileMock.js"
},
"transform": {
"^.+\\.js$": "babel-jest",
"\\.(ejs|ejx)$": "<rootDir>/tools/ejx-loader/jest.transformer.js"
}
},
and the transformer itself:
module.exports = {
process(src, filename, config, options){
console.log('????');
return 'module.exports = ' + require(`ejs-loader!./${filename}`);
//return require(`ejs-loader!./${filename}`);
}
};
Can you try changing module name mapper to -
{
"\\.(css|scss)$": "identity-obj-proxy",
"^.+\\.(gif|ttf|eot|svg|woff|woff2|ico)$": "<rootDir>/tools/fileMock.js"
"ejs-loader!(.*)": "$1",
}
This should at least invoke your custom transformer.
Also the custom transformer should be -
const _ = require('lodash');
module.exports = {
process(src, filename, config, options){
console.log('????');
return 'module.exports = ' + _.template(src);
}
};
It doesn't look like you've specified .ejs as a moduleFileExtension.
"jest": {
...
"moduleFileExtensions": ["js", "jsx", "ejs", "ejx"],
...
}
Also, ejs-loader will export the function using cjs syntax for you, so you can do the following in your transformer:
const loader = require('ejs-loader');
module.exports = {process: loader};
Work for me:
"jest": {
"moduleNameMapper": {
'\\.(ejs|ejx)$': '<rootDir>/jest-ejs.transformer.js'
},
moduleFileExtensions: ['js', 'json', 'jsx', 'ejs']
},
In jest-ejs.transformer.js
const loader = require('ejs-loader');
module.exports = {process: loader};

Webpack dll import is not defined

I am trying to put a bunch of libs on the DLL following guides like react-boilerplate and this one.
When I build and run, the DLL files are given as not defined.
I'm probably missing something I did a separated webpack to build the dll:
import webpack from 'webpack'
const library = '[name]'
export default {
entry: {
'lokka': ['lokka', 'lokka-transport-http', 'socket.io-client']
/** Other libs **/
},
output: {
filename: '[name].dll.js',
path: 'build/',
library: library
},
plugins: [
new webpack.DllPlugin({
path: 'build/[name]-manifest.json',
name: library
})
]
}
And added the references to the manifest.json
import webpack from 'webpack'
const desiredLibs = [
'lokka'
]
const plugins = desiredLibs.map((lib) => {
return new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(`../build/${lib}-manifest.json`)
})
})
export const dllReference = () => {
return { plugins }
}
export default dllReference
Was there anything else I should do?
On my case, it is complaining that lokka is not found when the code is run.
Turns out I (obviously) need to include the generated DLL on my scripts src AND copy it in the case of dev, since hot reloading would only serve the entry of it and it's dependencies, so for the dllReference and copy part it became:
import webpack from 'webpack'
import CopyWebpackPlugin from 'copy-webpack-plugin'
import path from 'path'
const desiredLibs = ['lokka', 'react', 'moment']
const copies = []
const plugins = desiredLibs.map((lib) => {
copies.push({
from: path.join(__dirname, `../compileResources/${lib}.dll.js`),
to: `dll`
})
return new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(`../compileResources/${lib}-manifest.json`)
})
})
plugins.push(
new CopyWebpackPlugin(copies)
)
/**
* Adds the dll references and copies the file
*/
export const dllReference = () => {
return { plugins }
}
export default dllReference
And then since I copied the dll's using the copy plugin I needed to add the scripts on the html. Really obvious on hindsight

Resources