I'm running a NestJS api with extensive code, everything is working fine, and it has almost full code coverage with all kinds of different mocks.
While trying to implement a test for the provider of a new module, I was prompted with this error:
Cannot find module 'jest-util'
Require stack:
- /node_modules/jest-runtime/build/index.js
- /node_modules/#jest/core/build/cli/index.js
- /node_modules/#jest/core/build/jest.js
- /node_modules/jest-cli/build/cli/index.js
- /node_modules/jest-cli/bin/jest.js
- /node_modules/jest/bin/jest.js
at Function.Module._resolveFilename (../node:internal/modules/cjs/loader:933:15)
at Function.Module._load (../node:internal/modules/cjs/loader:778:27)
at Module.require (../node:internal/modules/cjs/loader:999:19)
at require (../node:internal/modules/cjs/helpers:102:18)
I managed to isolate what was causing this behavior and it was this snippet of code below:
jest.mock("fs", () => ({
promises: {
writeFile: jest.fn().mockResolvedValue(undefined),
readFile: jest.fn().mockResolvedValue(Buffer.from('test')),
unlink: jest.fn().mockResolvedValue(undefined),
},
}));
Jest functions are being used all over the rest of the code below and above this statement, so it kinda doesn't make sense for me what is going on.
I expect some people are gonna wanna see the jest section on the package.json so I've added it below, but I don't think that's where the problem lies, as its working in more than 1000 different tests, all very similar to this one.
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"coverageReporters": [
"json-summary",
"json",
"html"
],
"testEnvironment": "node",
"setupFiles": [
"<rootDir>/test/config/envMock.ts"
]
},
jest version is 25.1.0
Anyone has any idea what is going on?
I added a restoreAllMocks after the already existing clearAllMocks on the beforeEach block of the testing module and the error went away.
Don't know exactly why though. I guess that maybe it has something to do with the mocks' states at certain points in the code, but I have no idea really.
Related
I am trying to add Jest to existing project and i have problem with configuration.
To solve problem with modules and es6 i added rollup-jest package (we are using rollup on our project)
To solve problem with handlebars i tried to use jest-handlebars package but i got problem
Code transformer's `process` method must return an object containing `code` key
with processed string. If `processAsync` method is implemented it must return
a Promise resolving to an object containing `code` key with processed string.
Code Transformation Documentation:
https://jestjs.io/docs/code-transformation```
Has anybody aby similar problem with jest plus handlebars configuration or can anybody help me with code transformator?
EDIT:
i added preprocessor.js file with:
module.exports = {
process(src) {
const code = `
const Handlebars = require('handlebars');
module.exports = Handlebars.compile(\`${src}\`);
`
return {
code: code
};
},
};
and change my packaged.json to:
``` "jest": {
"preset": "rollup-jest",
"collectCoverage": true,
"modulePaths": [
"./",
"./node_modules"
],
"moduleFileExtensions": [
"js",
"hbs",
"ts"
],
"transform": {
"\\.js$": "rollup-jest",
"^.+\\.hbs$": "<rootDir>/jestHbsTransformer.js",
"^.+\\.ts?$": "ts-jest"
}
}
}```
and it is still not working ;)
enter code here
I'm struggeling now for a couple of days to get my testsetup running. Rough outline: Vite, Svelte (with ts), Jest.
I'm using import.meta.env.SOMENAME for my environment vars although this works fine for development as soon as a component uses import.meta.env the test will fail with:
SyntaxError: Cannot use 'import.meta' outside a module
I've tried different transformers, babel-plugins and configs but never succeeded...
My jest config:
"jest": {
"globals": {
"ts-jest": {
"isolatedModules": true
}
},
"verbose": true,
"transform": {
"^.+\\.svelte$": [
"svelte-jester",
{
"preprocess": true
}
],
"^.+\\.ts$": "ts-jest",
"^.+\\.js$": "babel-jest"
},
"setupFilesAfterEnv": ["<rootDir>/setupTests.ts"],
"moduleFileExtensions": ["js", "ts", "svelte"]
}
babel.config.js
module.exports = {
presets: [
[
"#babel/preset-env",
{
targets: {
node: "current"
}
}
]
]
};
svelte.config.cjs
const sveltePreprocess = require('svelte-preprocess')
module.exports = {
emitCss: true,
preprocess: sveltePreprocess()
};
Among other things I tried to use #babel/plugin-syntax-import-meta but ended up with the same error. Also vite-jest looked very promising but again I couldn't make it work.
I appreciate every hint I can get. If I can provide any additional info please let me know. Also my knowledge of vite and babel is very limited so REALLY appreciate any help IU can get on this topic.
Update (Solution)
So If you use babel you could use babel-preset-vite. The approach with esbuild-jest from Apu is also good solution that many people use. Unfortunately those things didn't work for me so I decided to use a workaround with vite's define.
This workaround consists of two steps.
replace import.meta.env with process.env (if this is a deal breaker for you then I hope you have luck with the solutions above) You only have to replace the instances in files you want to test with jest.
Update Vite config with define. This step is necessary or your build will break (dev will still work)
vite.config.js
const dotEnvConfig = dotenv.config();
export default defineConfig({
define: {
"process.env.NODE_ENV": `"${process.env.NODE_ENV}"`,
"process.env.VITE_APP_SOMENAME": `"${process.env.VITE_APP_SOMENAME}"`
},
...
)};
I know this is just a workaround but maybe this helps someone. Thanks & Good Luck.
A more recent alternative to Jest that understands import.meta.env is Vitest.
It should require almost no additional configuration to get started and it's highly compatible with Jest so it requires few changes to the actual tests.
The advantages of Vitest over Jest for this use case are:
It's designed specifically for Vite and will process tests on demand
It will reuse your existing Vite configuration:
Any define variables will be replaced as expected
Extensions that Vite adds to import.meta will be available as usual
I was having issues with svelte component testing as well using jest. babel is not good at resolving import.meta. I used esbuild-jest to transform both ts and js files. It solves the issue with the import.meta. Here is my jest.config.cjs.
npm i esbuild esbuild-jest -D
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig');
const config = {
"transform": {
"^.+\\.svelte$": [
"svelte-jester",
{
"preprocess": true
}
],
"^.+\\.(ts|tsx|js|jsx)$": ["esbuild-jest"]
},
"moduleFileExtensions": [
"js",
"ts",
"tsx",
"svelte"
],
"setupFilesAfterEnv": [
"#testing-library/jest-dom/extend-expect"
],
"collectCoverageFrom": [
"**/*.(t|j)s",
"**/*.svelte"
],
coverageProvider: 'v8',
"coverageDirectory": "./coverage",
"coveragePathIgnorePatterns": [
"/node_modules/",
"/.svelte-kit/"
],
"moduleNameMapper": pathsToModuleNameMapper(compilerOptions.paths, {prefix: '<rootDir>/'})
};
module.exports = config;
I have jest.config.js as below:
module.exports = {
"roots": [
"<rootDir>/src"
],
"testMatch": [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)"
],
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
},
"testResultsProcessor": "jest-sonar-reporter",
"collectCoverage": true,
"collectCoverageFrom": [
"**/*.{ts,js}",
"!**/node_modules/**"
],
"coverageDirectory": "dist",
"coverageReporters": ["lcov"]
}
A report file test-report.xml is generated in the project root directory. How can I make it to be saved in dist directory?
Also you can configure it in jest configuration in package.json file
"jest": {
"coverageDirectory": "<rootDir>/reports",
}
According to your configuration a report file test-report.xml is generated by jest-sonar-reporter. You can change jest-sonar-reporter output directory by adding the following section to package.json:
"jestSonar": {
"reportPath": "dist"
}
Reference: https://github.com/3dmind/jest-sonar-reporter
You can add --coverageDirectory in your script for test case.
react-scripts test --coverageDirectory='test-coverage' --coverage --watchAll=false
My comment appeared to help, so here it is as an answer:
If you're using jest-junit-reporter, then you can change the output directory of the generated test-report.xml file by setting the TEST_REPORT_PATH environment variable with the desired path.
You can change the path like this.
coverageReporters: ["json", ["lcov", {"projectRoot": "../../"}]]
I'm using the following jest.unittest.json file (used via jest --config option):
{
"bail": false,
"verbose": true,
"transform": {
"^.+\\.(ts|tsx)$": "typescript-babel-jest"
},
"testPathIgnorePatterns": [
"<rootDir>/lib",
"<rootDir>/lib_es6",
"/node_modules/",
"fixtures.ts",
"/fixtures/"
],
"moduleFileExtensions": [
"js", "jsx", "ts", "tsx", "node"
],
"roots": [
"<rootDir>/src/__unittests__/Logger",
"<rootDir>/src/__unittests__/Renderer/renderer.test.ts"
],
"testRegex": "<rootDir>/src/__unittests__/.*\\.test.(ts|tsx|js|jsx)$"
}
Note the test files are src/unittests/Renderer/renderer.test.ts, and so on.
It used to work until jest v19, but after upgrading to v20, this config no longer works.
When I do jest --config jest.unittest.json --verbose, I get:
Pattern: "" - 0 matches
Is there anything wrong with my config?
Try to change testRegex to something like that:
"(/src/__unittests__/.*|\\.(test|spec))\\.(ts|tsx|js)$"
I'd say it's interesting, that you configure 2 roots and use only one path in your testRegex. Also in the documentation they catch the path and the file name without extension, which is not the way you do it. Catch the path and filename with the parenthesis. See the documentation there (I'd skip <rootDir> too as you probably want to use both roots): https://jestjs.io/docs/configuration#testregex-string--arraystring
I am wrtiting a project using TypeScript, Jest and the ts-jest NPM module.
When I run my test, I do get some amount of coverage, but the HTML report is not quite right:
Furthermore, some functions are being marked as untested even though they are certainly being called.
My package.json is set as follows:
{
"jest": {
"transform": {
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"testResultsProcessor": "<rootDir>/node_modules/ts-jest/coverageprocessor.js",
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.{ts,tsx}"
],
"coverageReporters": [
"html",
"json"
]
}
}
Is something wrong with my configuration?
UPDATE
Starting from jest#20 you can pass mapCoverage option and use coverage/lcov-report/index.html file.
OLD
I also have been struggling with this problem, but then I notice that line.
Long story short - coverage reports goes to coverage/remapped/html/index.html file.