nestjs testing - how to start a server with jest mocked modules - node.js

I already have e2e backend tests running using jest and some mocked modules using fastify and now that when I use app.listen it will be able to receive calls.
My problem:
I would like to start the nestjs server with the mocked jest modules to be able to call it from outside without the jest scope e.g. for vulnerability scanning of the api endpoints. I have some external dependencies that I want to exclude - this is why I would like to use my jest mocked nestjs modules.
if I try to used ts-node an error will be thrown in those mocked modules
command:
npx ts-node run.ts
file: run.ts
import { initializeApplication } from './app';
(async () => {
const app = await initializeApplication();
app.listen(3005, '0.0.0.0');
})();
error:
jest.fn(
^
ReferenceError: jest is not defined
I would like to be able to start the nestjs backend with jest mocked nestjs modules to make external api calls against the backend using fake dependencies.

Related

Jest, ES6 modules "does not provide export named"

I have an express app with a CRUD API (with sequelize) and I want to test it with Jest. I'm pretty new in unit-testing so I follow this guide, recommended by Jest's website.
The problem I have is that my app is built with ES6 modules and Jest ES6 modules is experimental and it seems that it doesn't "import" packages.
I have this test (took from the guide)
import request from 'supertest';
import app from '../app';
describe('Test the root path', () => {
test('It should response the GET method', done => {
request(app)
.get('/')
.then(response => {
expect(response.statusCode).toBe(404);
done();
});
});
});
And when I launched it (with NODE_OPTIONS=--experimental-vm-modules npx jest I had to follow this jest wiki page), It says that
'sequelize' does not provide an export named 'DataTypes' and when I launch my app normally (like with npm start) it works fine, without any problems.
(the complete error log):
(node:49576) ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
FAIL __tests__/app_test.js
● Test suite failed to run
SyntaxError: The requested module 'sequelize' does not provide an export named 'DataTypes'
at Runtime.linkAndEvaluateModule (node_modules/jest-runtime/build/index.js:779:5)
at TestScheduler.scheduleTests (node_modules/#jest/core/build/TestScheduler.js:333:13)
at runJest (node_modules/#jest/core/build/runJest.js:404:19)
at _run10000 (node_modules/#jest/core/build/cli/index.js:320:7)
at runCLI (node_modules/#jest/core/build/cli/index.js:173:3)
(and my Jest config)
// Sync object
/** #type {import('#jest/types').Config.InitialOptions} */
export default async () => {
return {
verbose: true,
transform: {},
};
};
Am I doing something wrong ? Should I change to commonJS instead of ES6
Thank you.
This is a known problem in Jest: #9771. It is said to be fixed in jest#28.0.0-alpha.0.
An interesting hack to work around this problem is to remove the main field from the package.json of the imported project.

why is jest not required?

I have a react app and I don't know why I don't need to require the jest module.
import Task from './Task';
describe('class Task', () => {
it('inProgress()', () => {
var t = new Task("prova");
expect(t.isInProgress()).not.toBeTruthy();
});
});
The test command for create-react-app runs react-scripts test --env=jsdom.
The script for react-scripts test requires jest on this line and after configuring everything it runs jest on this line.
jest then finds your test files, loads them, and runs them.
In other words, your tests don't load and run jest, it's jest that loads and runs your tests.
Since your tests run within jest they can take advantage of the globals, expect, environment, etc. provided by jest without having to "require or import anything to use them".

Import jest object when not using jest runner

What do I need to import/require in order to access the magic jest object that contains jest.fn when not running my code with jest?
Jest now exports the jest-mock package seperately (https://github.com/facebook/jest/tree/master/packages/jest-mock).
import jestMock from 'jest-mock';
const mockFunction = jestMock.fn();

mock module which does not exist?

When i run my mocha tests in my meteor app by:
node_modules/.bin/mocha --compilers js:babel-core/register //..opts
i get a problem when my module under test wants to import:
import { Meteor } from 'meteor/meteor';
So i tried to mock it with mockery:
mockery.enable();
moduleUnderTest = '../moduleUnderTest';
mockery.registerAllowable(moduleUnderTest);
meteorMock = {};
mockery.registerMock('Meteor', meteorMock);
Unfortunately the module cannot be found
Error: Cannot find module 'meteor/meteor'
So the mocking of Meteor cannot be done.
Is there a way how i can fake the location meteor/meteor?
(Alternate Solution: If i can get access to the Meteor Environment in my mocha test)
If you look at the documentation, you'll see that .registerAllowable takes a string, not a module. You also need to give the exact module name that you are mocking, and provide a fake module with the values you want.
So:
var mockery = require("mockery");
mockery.enable();
mockery.registerAllowable("./moduleUnderTest");
// We want Meteor to have the value "foo". You probably want something
// different.
var meteorMock = { Meteor: "foo" };
// We mock 'meteor/meteor' because that's what's imported.
mockery.registerMock('meteor/meteor', meteorMock);
If you think about it, what you were doing cannot work. You were requiring the module before Mockery is configured for mocking 'Meteor', so Node loads your module, and then tries to load Meteor before the mock is available, and you get a failure.
Moreover, Meteor mocks modules so when you register a mock, you have to give a module name, not the name of a variable.

How to test Angular2 pipe in nodejs with mocha without karma

I'd like to be able to test an Angular2 pipe purely in nodejs environment without including karma etc.
It is possible to use typescript files as test suites for mocha
https://templecoding.com/blog/2016/05/05/unit-testing-with-typescript-and-mocha/
But when I have a import {Pipe} from '#angular/core' it gives me
/Users/foo/node_modules/#angular/core/src/util/decorators.js:173
throw 'reflect-metadata shim is required when using class decorators';
^
reflect-metadata shim is required when using class decorators
Even if I write require('reflect-metadata') in my test file it still breaks with the same error.
Angular internally has this check:
(function checkReflect() {
if (!(Reflect && Reflect.getMetadata)) {
throw 'reflect-metadata shim is required when using class decorators';
}
})();
And after requireing reflect-matadata I indeed have Reflect on the global object, however it still doesn't work...
Anyway is there a way to test an Angular pipe purley in nodejs with mocha?
I'm using webpack to bundle the app so the file I'm requring in my test file looks like this:
import {Pipe} from '#angular/core';
#Pipe({
name: 'filterBy'
})
export class FilterByPipe {
transform(items = [], prop, val) {
return items.filter(someFilteringAlgorithm(prop, val));
}
}
I didn't test pipes yet, but here a post that explain how to test Angular 2 application in Node with Mocha. But It use Webpack instead of ts-node : Here
Hope It can help.

Resources