Karma startup and teardown config - javascript

When running Karma tests, I would like to start HTTP server to do some cross-origin network requests in tests. Is there a natural way to start the server before Karma tests start and close the server when Karma exits.

The solution is to use new karma.Server():
// #ts-check
const karma = require('karma');
const path = require('path');
const {createEchoServer} = require('./echo-server');
async function run() {
const configPath = path.join(__dirname, './karma.conf.js');
const karmaConfig = karma.config.parseConfig(configPath, {});
const echoServer = await createEchoServer();
const karmaServer = new karma.Server(karmaConfig, () => {
echoServer.close();
});
karmaServer.start();
}
run();

Related

Mocha and Chai test never starts when running an Express app

I'm trying to test an Express API with Mocha and Chai.
My structure is as follows:
server.js
const express = require('express');
...
const loadCredentials = () => ({
...
})
const application = () => {
console.log('This is a log i should always see');
const app = express();
app.use('/api', authentication, authorization('#data/accounts'), router);
...
return app;
};
if (require.main === module) {
application.listen(443)
...
}
module.exports = { application };
test.js
const { application } = require('../server/src/server');
describe('Some async test', async () => {
it(, async () => {
console.log('I should really see this log!!');
server = application();
const res = await chai.request(server).get('/api');
...test stuff...
}
}
When I lerna run test (which runs mocha ./test.js --timeout 60000) the test never executes.
lerna notice cli v3.10.7
lerna info Executing command in 1 package: "yarn run test"
However, if I disable the call to application, the test starts (and fails because server is undefined).
I also tried refactoring application and passing an express() parameter to application(app) from the test, and I get the same behavior.
The test runs if I run it from WebStorm as an individual test.
Needless to say the server works when I yarn run it.
Any help would be appreciated.

chai.use(chaiHttp); Once or in every test file?

Adding Chai HTTP (https://www.chaijs.com/plugins/chai-http/) to a Node project tests.
Using the plugin (as in the documentation) is using:
var chai = require('chai')
, chaiHttp = require('chai-http');
chai.use(chaiHttp);
I'm wonder if I need to add chai.use(chaiHttp); in every test file I'm using chaiHttp? or can I setup chaiHttp once in one of the tests?
can it be in a common file?
From mocha v8.2.0, you can use https://mochajs.org/#global-fixtures.
global fixtures:
Are guaranteed to execute once and only once
You can use TEST FIXTURE DECISION-TREE WIZARD THING.
This flowchart will help you decide which of hooks, root hook plugins or global fixtures you should use.
After knowing this, here is an example:
a.test.js:
const chai = require('chai');
const { expect } = chai;
describe('a', () => {
it('should pass', () => {
expect(chai.request).to.be.a('function');
});
});
b.test.js:
const chai = require('chai');
const { expect } = chai;
describe('b', () => {
it('should pass', () => {
expect(chai.request).to.be.a('function');
});
});
fixtures.js:
var chai = require('chai'),
chaiHttp = require('chai-http');
exports.mochaGlobalSetup = function () {
chai.use(chaiHttp);
console.log('setup chaiHttp plugin');
};
Run the test suites and the result:
npx mocha --require fixtures.js ./**/*.test.js
setup chaiHttp plugin
a
✓ should pass
b
✓ should pass
2 passing (5ms)

How to test with Jest after connecting to MongoDB?

I'm trying to set up testing for various routes in my Express server that require connectivity to my MongoDB database.
I'm not sure how to structure the Jest file in order to allow for testing. In my normal index.js file, I'm importing the app, and running app.listen within the connect .then call, like this:
const connect = require("../dbs/mongodb/connect");
connect()
.then(_ => {
app.listen(process.env.PORT, _ => logger.info('this is running')
})
.catch(_ => logger.error('The app could not connect.');
I've tried running the same setup in my test.js files, but it's not working.
For example:
const connect = require("../dbs/mongodb/connect");
const request = require("supertest");
const runTests = () => {
describe("Test the home page", () => {
test("It should give a 200 response.", async () => {
let res = await request(app).get("/");
expect(res.statusCode).toBe(200);
});
});
};
connect()
.then(_ => app.listen(process.env.PORT))
.then(runTests)
.catch(err => {
console.error(`Could not connect to mongodb`, err);
});
How is it possible to wait for a connection to MongoDB before running my tests?
So, turns out there were a few changes that I had to make. Firstly, I had to load in my .env file before running the tests. I did this by creating a jest.config.js file in the root of my project:
module.exports = {
verbose: true,
setupFiles: ["dotenv/config"]
};
Then within the actual testing suite, I'm running beforeEach to connect to the MongoDB server.
const connect = require("../dbs/mongodb/connect");
const app = require("../app");
const request = require("supertest");
beforeEach(async() => {
await connect();
});
describe("This is the test", () => {
test("This should work", async done => {
let res = await request(app).get("/home");
expect(res.statusCode).toBe(200);
done();
})
});

How to write integration test with Jest and Express?

I am trying to write integration tests with a third party microservice (Assume it is call Service). When a request is sent to Service, it will fire a webhook. What I am trying to do is to test it the webhook parsed correctly.
import express from "express";
import bodyParser from "body-parser";
import { handleHook} from "./hook";
export const app = express();
app.use(bodyParser.json(), handleHook);
describe("integration", () => {
test("hook", async () => {
const mock = jest.fn();
app.post("/", (req, res) => {
mock(req);
res.send("");
});
const p = new Promise<Server>(resolve => {
const server = app.listen(3000, () => {
resolve(server);
});
});
const server = await p;
await upload();
jest.useFakeTimers();
setTimeout(() => {
server.close();
}, 15000);
jest.runAllTimers();
expect(mock).toHaveBeenCalledTimes(4);
});
});
However, I got two problems. First, I got
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue
but using --detectOpenHandles does not show how to troubleshoot this issue.
Second, because the webhook is fire asynchronously, how can I ensure to catch all of them or wait for a period of time to timeout.

How to run(sync) multiple .js files from a directory

I'm trying to run multiple .js files from a directory:
exampleDir/test.js
console.log('hi');
run.js
const fs = require('fs');
const {execFileSync} = require('child_process');
const testsFolder = './exampleDir/';
const files = fs.readdirSync(testsFolder);
const funcs = files.map(function(file) {
const out = execFileSync(`node ${testsFolder}${file}`);
console.log(out.toString());
});
however I get:
> example#1.0.0 test /home/perdugames/example
> node ./run.js
child_process.js:624
throw err;
^
Error: spawnSync node ./exampleDir/test.js ENOENT
...
File paths should be specified unambiguously, preferably independent of current working directory and relative to current module. To create a new Node process, there are spawn and spawnSync in child_process:
...
const path = require('path');
const testsFolder = path.join(__dirname, './exampleDir/');
const files = fs.readdirSync(testsFolder);
const funcs = files.map(function(file) {
const filePath = path.join(testsFolder, file);
const out = spawnSync(filePath);
console.log(out.stdout.toString());
});

Categories