global is not defined in jest test file - node.js

global variable in JS is not able to access in jest test files, also not able to change the values which are already defined in global.
the work around I have did is as follow:
require('./../../../../bin/global');
describe('gloablAccessMethod', () => {
beforeEach(() => {
// jest.spyOn(regionConfig,'global.regionConfig').mockImplementation(() => ({
// 'ENABLE_CONFIG' : false
// }));
global.regionConfig.ENABLE_CONFIG = false;
});
const PHONE_PREFIX_SG = 65;
it('should access mock global variables', () =>{
//some sample tests
});
});
jest configuration
"jest": {
"timers": "fake",
"testEnvironment": "node",
"setupFiles": [
"./.jest/setEnv.js"
],
"setupFilesAfterEnv": [
"./.jest/setup.js"
],
"coverageReporters": [
"text",
"cobertura"
],
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.{js,jsx}"
]
},```

Related

node-loader not handling node_modules file

When running
npm run electron:serve
I get this error:
in ./node_modules/msnodesqlv8/build/Release/sqlserverv8.node
Module parse failed: Unexpected character '�' (1:2)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
I think I understand the error. My webpack doesn't know how to handle the .node file in this dependency ("msnodesqlv8": "^2.2.0")
I have tried adding node-loader but I've not had any success with it. I have tried configuring it in my vue.config.js like this:
module.exports = {
transpileDependencies: [
'vuetify'
],
configureWebpack: {
devtool: 'source-map'
},
pluginOptions: {
electronBuilder: {
preload: 'preload/preload.js',
"directories": {
"buildResources": "build"
},
mainProcessWatch:['src/services/background/**'],
"files": [
"build/**/*",
"!node_modules"
],
"win": {
"asar": false,
"target": "nsis",
"icon": "build/icon.ico"
},
"nsis": {
"installerIcon": "build/icon.ico",
"installerHeaderIcon": "build/icon.ico",
"deleteAppDataOnUninstall": true
}
}
},
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].title = "Configuration Utility";
return args;
});
config.module
.rule('node')
.test(/\.node$/)
.use('node-loader')
.loader('node-loader')
.end();
config.module
.rule('pug')
.test(/\.pug$/)
.use('pug-plain-loader')
.loader('pug-plain-loader')
.end();
}
}
I also tried adding a separate webpack.config.js with no success:
module.exports = {
target: "node",
node: {
__dirname: false,
},
module: {
rules: [
{
test: /\.node$/,
loader: "node-loader",
},
],
},
};
How can I get this working?
You need to move the node loader into the chainWebpack of the electron builder for this to work.
module.exports = {
transpileDependencies: [
'vuetify'
],
configureWebpack: {
devtool: 'source-map'
},
pluginOptions: {
electronBuilder: {
preload: 'preload/preload.js',
"directories": {
"buildResources": "build"
},
// THESE NEXT 3 LINES HERE:
chainWebpackMainProcess: config => {
config.module.rule('node').test(/\.node$/).use('node-loader').loader('node-loader').end()
},
mainProcessWatch:['src/services/background/**'],
"files": [
"build/**/*",
"!node_modules"
],
"win": {
"asar": false,
"target": "nsis",
"icon": "build/icon.ico"
},
"nsis": {
"installerIcon": "build/icon.ico",
"installerHeaderIcon": "build/icon.ico",
"deleteAppDataOnUninstall": true
}
}
},
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].title = "Configuration Utility";
return args;
});
config.module
.rule('pug')
.test(/\.pug$/)
.use('pug-plain-loader')
.loader('pug-plain-loader')
.end();
}
}

Jest didn't parse to import a file

I am trying to test my Next.js project with Jest and Enzyme. When I try to import a file from my components to test it, throws error though. Here's my files...
In the package.json my jest configuration are:
"jest": {
"setupFilesAfterEnv": "<rootDir>/jest.setup.js",
"testPathIgnorePatterns": [
"<rootDir>/.next/",
"<rootDir>/node_modules/"
],
"transform": {
"\\.(gql|graphql)$": "jest-transform-graphql",
".*": "babel-jest",
"^.+\\.js?$": "babel-jest"
}
},
"//": "I prefer this over a .babelrc file",
"babel": {
"env": {
"development": {
"presets": [
"next/babel"
],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true
}
]
]
},
"production": {
"presets": [
"next/babel"
],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true
}
]
]
},
"test": {
"presets": [
[
"next/babel",
{
"preset-env": {
"modules": "commonjs"
}
}
]
],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true
}
]
]
}
}
}
And subsequently in jest.setup.js :
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
However I always encounter this error anytime I want to **import a file **(In here for example I try to import a file namely "import ItemComponent from '../components/Item';"):
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest
cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform
your files, ignoring "node_modules". SyntaxError: Unexpected
identifier
Details:
SyntaxError: C:\Users\Welcome\Desktop\Advanced-React-master\sick-fits\frontend\__tests__\Item.test.js: Unexpected token (20:28)
18 | describe('<Item/>', () => {
19 | it('renders and matches the snapshot', () => {
> 20 | const wrapper = shallow(<ItemComponent item={fakeItem} />);
| ^
21 | expect(wrapper).toMatchSnapshot();
22 | });
23 | // it('renders and displays properly', () => {
at Parser.raise (node_modules/#babel/parser/lib/index.js:3939:15)
at Parser.unexpected (node_modules/#babel/parser/lib/index.js:5248:16)
at Parser.parseExprAtom (node_modules/#babel/parser/lib/index.js:6328:20)
at Parser.parseExprSubscripts (node_modules/#babel/parser/lib/index.js:5924:21)
at Parser.parseMaybeUnary (node_modules/#babel/parser/lib/index.js:5903:21)
at Parser.parseExprOps (node_modules/#babel/parser/lib/index.js:5812:21)
at Parser.parseMaybeConditional (node_modules/#babel/parser/lib/index.js:5784:21)
at Parser.parseMaybeAssign (node_modules/#babel/parser/lib/index.js:5731:21)
at Parser.parseExprListItem (node_modules/#babel/parser/lib/index.js:6995:18)
at Parser.parseCallExpressionArguments (node_modules/#babel/parser/lib/index.js:6124:22)
Any help would be appreciated
Try removing these two lines from your package.json:
".*": "babel-jest",
"^.+\\.js?$": "babel-jest"
In theory, these shouldn't be needed: https://jestjs.io/docs/en/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
The custom configuration you have added might be causing issues. In theory, jest should transform your js files by default using babel-jest. I've certainly had a recent NextJS project work with jest with no babel-jest config declared in my package.json.

.env for jest and nest is not the same

I want to test a nest api, for that I create one file .env and for my dev I create a .env.development file.
Which I launch some test with jest my first test uses the good file: .env but the second test use the wrong file .env.development.
How I load the .env in nest :
import {Module} from '#nestjs/common';
import {ConfigService} from './config.service';
#Module({
providers: [{
provide: ConfigService,
useValue: new ConfigService(`.env${process.env.NODE_ENV}`),
}],
exports: [ConfigService],
})
export class ConfigModule {}
How I load the .env in jest :
"test:watch": "NODE_ENV='' jest --watch",
"jest": {
"displayName": {
"name": "API",
"color": "yellow"
},
"verbose": true,
"runner": "jest-serial-runner",
"testSequencer": "../src/test/sequencer.jest.js",
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "../coverage",
"testEnvironment": "node",
"preset": "#shelf/jest-mongodb",
"setupFiles": [
"dotenv/config" <------------------------| here
]
},
The test for my .env (is ok the right .env is loaded)
describe('🛠️ tests for env file', () => {
it('should have a db_user', () => {
expect(process.env.db_user).toBeDefined();
});
it('should have a db_pass', () => {
expect(process.env.db_pass).toBeDefined();
});
it('should have a db_uri', () => {
expect(process.env.db_uri).toBeDefined();
});
it('should have a db_port', () => {
expect(process.env.db_port).toBeDefined();
});
it('should have a db_name', () => {
expect(process.env.db_name).toBeDefined();
});
});
The test that loads the wrong .env (I put a wrong ip for the db in .env.development, so the test failed)
import { Test, TestingModule } from '#nestjs/testing';
import * as request from 'supertest';
import {AppModule} from '../app.module';
// remove console.log
console.log = jest.fn();
describe('🗜️ UserController', () => {
let app;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
/** valid test for create a admin user */
it('post /users valid test for create a admin user', () => {
return request(app.getHttpServer())
.post('/users')
.send({
jwt: '',
firstname: 'admin',
lastname: 'admin',
mail: 'admin#gmail.com',
password: 'test'
})
.expect(201);
});
});
It looks like there is a missing . after .env in this line:
new ConfigService(`.env${process.env.NODE_ENV}`)
However, the extra period is only needed when process.env.NODE_ENV contains a value so I would do something like:
const NODE_ENV = process.env.NODE_ENV ? `.${process.env.NODE_ENV}` : '';
//...
new ConfigService(`.env${NODE_ENV}`)
This way you will either end up with new ConfigService('.env') or new ConfigService('.env.development')

Jest's globalSetup make my tests to not being recognized

So I was following this example to make a test with mongodb on jest, but after configuring everything I just get this when running jest:
If I remove globalSetup from jest.config.js, the tests appear although with errors because of mongo-enviroment and teardown configs been dependents on globalSetup:
If I run jest --debug I get this:
{
"configs": [
{
"automock": false,
"browser": false,
"cache": true,
"cacheDirectory": "/tmp/jest_rs",
"clearMocks": false,
"coveragePathIgnorePatterns": [
"/node_modules/"
],
"detectLeaks": false,
"detectOpenHandles": false,
"errorOnDeprecated": false,
"filter": null,
"forceCoverageMatch": [],
"globals": {},
"haste": {
"providesModuleNodeModules": []
},
"moduleDirectories": [
"node_modules"
],
"moduleFileExtensions": [
"js",
"json",
"jsx",
"node"
],
"moduleNameMapper": {},
"modulePathIgnorePatterns": [],
"name": "9f5155d702743ad8d949d6d219c1bc22",
"prettierPath": null,
"resetMocks": false,
"resetModules": false,
"resolver": null,
"restoreMocks": false,
"rootDir": "/home/mauricio/work/growthbond/gbnd1",
"roots": [
"/home/mauricio/work/growthbond/gbnd1"
],
"runner": "jest-runner",
"setupFiles": [
"/home/mauricio/work/growthbond/gbnd1/node_modules/regenerator-runtime/runtime.js"
],
"setupTestFrameworkScriptFile": "/home/mauricio/work/growthbond/gbnd1/testConfig/setupScript.js",
"skipFilter": false,
"snapshotSerializers": [],
"testEnvironment": "/home/mauricio/work/growthbond/gbnd1/testConfig/mongo-environment.js",
"testEnvironmentOptions": {},
"testLocationInResults": false,
"testMatch": [
"**/__tests__/**/*.js?(x)",
"**/?(*.)+(spec|test).js?(x)"
],
"testPathIgnorePatterns": [
"/node_modules/"
],
"testRegex": "",
"testRunner": "/home/mauricio/work/growthbond/gbnd1/node_modules/jest-jasmine2/build/index.js",
"testURL": "http://localhost",
"timers": "real",
"transform": [
[
"^.+\\.jsx?$",
"/home/mauricio/work/growthbond/gbnd1/node_modules/babel-jest/build/index.js"
]
],
"transformIgnorePatterns": [
"/node_modules/"
],
"watchPathIgnorePatterns": []
}
],
"globalConfig": {
"bail": false,
"changedFilesWithAncestor": false,
"collectCoverage": false,
"collectCoverageFrom": null,
"coverageDirectory": "/home/mauricio/work/growthbond/gbnd1/coverage",
"coverageReporters": [
"json",
"text",
"lcov",
"clover"
],
"coverageThreshold": null,
"detectLeaks": false,
"detectOpenHandles": false,
"errorOnDeprecated": false,
"expand": false,
"filter": null,
"globalSetup": "/home/mauricio/work/growthbond/gbnd1/testConfig/setup.js",
"globalTeardown": "/home/mauricio/work/growthbond/gbnd1/testConfig/teardown.js",
"listTests": false,
"maxWorkers": 3,
"noStackTrace": false,
"nonFlagArgs": [],
"notify": false,
"notifyMode": "always",
"passWithNoTests": false,
"projects": null,
"rootDir": "/home/mauricio/work/growthbond/gbnd1",
"runTestsByPath": false,
"skipFilter": false,
"testFailureExitCode": 1,
"testPathPattern": "",
"testResultsProcessor": null,
"updateSnapshot": "new",
"useStderr": false,
"verbose": true,
"watch": false,
"watchman": true
},
"version": "23.6.0"
}
Note that
"testMatch": [
"**/__tests__/**/*.js?(x)",
"**/?(*.)+(spec|test).js?(x)"
],
looks perfectly fine.
Related files
jest.config.js:
module.exports = {
globalSetup: './testConfig/setup.js',
globalTeardown: './testConfig/teardown.js',
testEnvironment: './testConfig/mongo-environment.js',
setupTestFrameworkScriptFile: './testConfig/setupScript.js',
verbose: true
}
setup.js (globalSetup):
const path = require('path');
const fs = require('fs');
const MongodbMemoryServer = require('mongodb-memory-server');
const globalConfigPath = path.join(__dirname, 'globalConfig.json');
const mongod = new MongodbMemoryServer.default({
instance: {
dbName: 'jest'
},
binary: {
version: '3.2.18'
},
autoStart: false,
});
module.exports = async () => {
if (!mongod.isRunning) {
await mongod.start();
}
const mongoConfig = {
mongoDBName: 'jest',
mongoUri: await mongod.getConnectionString()
};
// Write global config to disk because all tests run in different contexts.
fs.writeFileSync(globalConfigPath, JSON.stringify(mongoConfig));
console.log('Config is written');
// Set reference to mongod in order to close the server during teardown.
global.__MONGOD__ = mongod;
process.env.MONGO_URL = mongoConfig.mongoUri;
};
teardown.js:
module.exports = async function() {
await global.__MONGOD__.stop();
};
mongo-environment.js:
const NodeEnvironment = require('jest-environment-node');
const path = require('path');
const fs = require('fs');
const globalConfigPath = path.join(__dirname, 'globalConfig.json');
module.exports = class MongoEnvironment extends NodeEnvironment {
constructor(config) {
super(config);
}
async setup() {
console.log('Setup MongoDB Test Environment');
const globalConfig = JSON.parse(fs.readFileSync(globalConfigPath, 'utf-8'));
this.global.__MONGO_URI__ = globalConfig.mongoUri;
this.global.__MONGO_DB_NAME__ = globalConfig.mongoDBName;
await super.setup();
}
async teardown() {
console.log('Teardown MongoDB Test Environment');
await super.teardown();
}
runScript(script) {
return super.runScript(script);
}
};
user.test.js (mongodb related test):
const MongoClient= require('mongodb');
const User = require('../../db/models/user');
let connection;
let db;
beforeAll(async () => {
connection = await MongoClient.connect(global.__MONGO_URI__);
db = await connection.db(global.__MONGO_DB_NAME__);
});
afterAll(async () => {
await connection.close();
await db.close();
});
describe('Password Encription', async () => {
const uEmail = 'test#a.com';
const uPass = '123test';
var testUser = new User({
email:uEmail ,
password: uPass
});
await testUser.save()
test('Encripted password string is different to plain password', async () => {
user = await User.findOne({ email: uEmail });
expect(user.password).not.toEqual(uPass);
});
test('ComparePassword method verify that plain password is the same that encrypted password', async () => {
rightPassword = await user.comparePassword(uPass);
expect(rightPassword).toBeTrue();
});
test('ComparePassword method verify that altered plain password is not the same that encrypted password', async () => {
wrongPassword = await user.comparePassword(uPass+'random');
expect(rightPassword).not.toBeTrue();
});
});
authService.test.js:
require('dotenv').config()
const authS = require('../../services/authService');
const jwt = require('jsonwebtoken');
describe('Auth Services',()=>{
const payload = {test:'This is a test'}
const user = {id:101}
const mockSecret = 'SECRET123HAAJAHJSoafdafda'
const token = authS.jwtSign(user,payload)
test('JWT sign', () => {
expect(authS.jwtSign(user,payload)).toBeString();
});
test('JWT verify different secret', ()=>{
badToken = jwt.sign(
payload,
mockSecret,
{ subject:String(user.id),
expiresIn:'1h'
}
);
expect(()=>authS.jwtVerify(badToken)).toThrowError(jwt.JsonWebTokenError)
})
test('JWT verify payload', ()=>{
expect(authS.jwtVerify(authS.jwtSign(user,payload))).toMatchObject(payload)
})
})
My environment:
node v11.0.0
jest 23.6.0
As a matter of fact I know that my test non mongodb related run if I comment
globalSetup: './testConfig/setup.js',
globalTeardown: './testConfig/teardown.js',
testEnvironment: './testConfig/mongo-environment.js',
from jest.config.js :
My problem was that I had another GlobalSetup file and they were conflicting. In my custom GlobalSetup I imported the #Shelf/jest-mongodb/setup and add it to mine.
const jestMongoSetup = require("#shelf/jest-mongodb/setup")
module.exports = async () => {
process.env.TZ = "UTC" //My config
await jestMongoSetup()
}

Cannot get ava transpile to work with relatively-imported files

The ES6 import works in this file, but generates an unexpected token import error when I'm importing relative files such as my Mongoose User model.
import mongoose from 'mongoose';
^^^^^^
SyntaxError: Unexpected token import
.babelrc
{
"presets": [
["es2015", { "modules": false }]
],
"plugins": [
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-export-extensions"
]
}
package.json
"ava": {
"require": [
"babel-register"
]
}
users.test.js
import test from 'ava'
import axios from 'axios'
import User from '../../models/user'
import { USER_REGISTRATION_ROUTES } from '../helpers/_test.properties.js'
test('user registration api works', async function (t) {
const email = `test${Date.now()}#example.com`
const userRegistrationData = {
email,
first_name: "john",
last_name: "doe",
password: "password"
}
await axios.post(USER_REGISTRATION_ROUTES, userRegistrationData)
.then(response => {
const data = response.data.data
const user = data.user
t.deepEqual(response.status, 200, 'Verify: response is successful')
t.deepEqual(data.registered, true, 'Verify: user is registered')
t.truthy(Object.keys(user).length > 0,
'Verify: if registered, user object is returned')
t.truthy(user.authentication_token,
'Verify: token is generated on successful registration')
})
.catch((err) => {
t.fail(`Cannot make requst to register user ${err}`)
})
User.remove({ email }, function (err) {
if (err) {
console.log('error')
} else {
console.log('success deleting test user')
}
})
})
Don't think import is supported in nodejs yet. You have to use require.
const mongoose = require('mongoose');
The answer that worked for me was the following suggested by Serge Seletskyy here. The es2017 preset is required for ES2017 features such as async await.
.babelrc
{
"presets": [
"es2017",
"#ava/stage-4",
"stage-3"
],
"plugins": [
"transform-runtime"
]
}
package.json
"ava": {
"require": [
"babel-register"
],
"babel": "inherit"
}
install modules
yarn add babel-register babel-preset-es2017 #ava/babel-preset-stage-4 babel-plugin-transform-runtime babel-preset-stage-3 --dev
Running ./node_modules/.bin/ava --verbose should now work
Non-test files are loaded through babel-register, which applies your .babelrc. However you've disabled module transpilation. I see in another comment that you're using Webpack. Try adding a environment config for Babel which restores module transpilation. From the top of my head:
{
"presets": [
["es2015", { "modules": false }]
],
"plugins": [
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-export-extensions"
],
"env": {
"test": {
"presets": [
["es2015", { "modules": true }]
]
}
}
}
This should work with the latest AVA version.
My version of Ava is 1.0.0-beta.4, and below is the solution that worked for me:
Add the following to your package.json
"ava": {
"require": [
"#babel/register"
]
}
Then npm install --save-dev #babel/register, and run test again.

Resources