I'm trying to do BDD tests to cover my code, but I got this error :
I'm trying to do BDD tests to cover my code, but I got this error :
I'm trying to do BDD tests to cover my code, but I got this error :
I'm trying to do BDD tests to cover my code, but I got this error :
I'm trying to do BDD tests to cover my code, but I got this error :
app.js
"use strict";
var app = require("express")();
var pg = require("pg");
var http = require("http");
var https = require("https");
require("./config/config");
var server;
swaggerTools.initializeMiddleware(swaggerConfig, function (middleware) {
// Interpret Swagger resources and attach metadata to request - must be first in swagger-tools middleware chain
app.use(middleware.swaggerMetadata());
var sayHello = ( type ) => {
return ( ) => {
console.log( `${global.gConfig.app.name} (${global.gConfig.app.desc}) listening for ${type.toUpperCase()} connections on port ${global.gConfig.ports[type]}`);
}
}
if( global.gConfig.ports.http ) {
http.createServer(app).listen( global.gConfig.ports.http, sayHello('http') );
server=app.listen(global.gConfig.ports.http);
}
if( global.gConfig.ports.https ) {
server=app.listen(global.gConfig.ports.https);
}
});
module.exports = {
serve:server,
app:app
};
test.js
let chai = require('chai');
let expect = require('chai').expect;
let chaiHttp = require('chai-http');
var app=require('../').app;
var server=require('../').server;
let should = require('chai').should;
var request = require("supertest").agent(server);
chai.use(chaiHttp);
describe('Caracteristiques', () => {
after(function (done) {
server.close();
done();
});
it('returns an array of Carateristiques', (done) => {
//chai.request(server)
request
.get('caracteristiques')
.set('Authorization', 'Bearer token')
.end((err, res) => {
console.log("res :",res);
expect(res.status).to.equal(200);
done();
});
});
})
the error :
1) Uncaught error outside test suite:
Uncaught Error: listen EADDRINUSE :::3001
at Object._errnoException (util.js:992:11)
at _exceptionWithHostPort (util.js:1014:20)
at Server.setupListenHandle [as _listen2] (net.js:1355:14)
at listenInCluster (net.js:1396:12)
at Server.listen (net.js:1480:7)
at Function.listen (node_modules\express\lib\application.js:618:24)
at C:\Users\zya\Documents\Tdbc-api\tdbc-api\app.js:75:17
at C:\Users\zya\Documents\Tdbc-api\tdbc-api\node_modules\swagger-tools\index.js:85:7
at cbWrapper (node_modules\swagger-tools\lib\specs.js:1023:5)
at validateSwagger2_0 (node_modules\swagger-tools\lib\specs.js:1018:3)
at validateSemantically (node_modules\swagger-tools\lib\specs.js:1028:5)
at C:\Users\zya\Documents\Tdbc-api\tdbc-api\node_modules\swagger-tools\lib\specs.js:1221:7
at C:\Users\zya\Documents\Tdbc-api\tdbc-api\node_modules\swagger-tools\lib\specs.js:1061:29
at C:\Users\zya\Documents\Tdbc-api\tdbc-api\node_modules\swagger-tools\lib\specs.js:707:12
at C:\Users\zya\Documents\Tdbc-api\tdbc-api\node_modules\swagger-tools\lib\specs.js:683:9
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
at startup (bootstrap_node.js:191:16)
at bootstrap_node.js:612:3
2) Caracteristiques
returns an array of Carateristiques:
TypeError: Cannot read property 'address' of undefined
at Test.serverAddress (node_modules\supertest\lib\test.js:55:18)
at new Test (node_modules\supertest\lib\test.js:36:12)
at TestAgent.(anonymous function) [as get] (node_modules\supertest\lib\agent.js:52:15)
at Context.it (test\caracteristiques.js:31:14)
3) Caracteristiques
"after all" hook:
TypeError: Cannot read property 'close' of undefined
at Context.<anonymous> (test\caracteristiques.js:23:16)
I think the set up id good, can any one helop please ?
i think it's not working because you are trying to enable the server in the same port each time your test is executed. [Or you have your sever running while you execute your tests].
Try to shut down your server while you execute your tests.
FYI: You are exporting your server main module as "serve", then you try to acceed to it using require(path).server instead of require(path).serve;
Related
I am running into issues when testing my express application. All tutorials use app.listen instead of https.createServer and I don't know how to properly use testing frameworks with the latter. The code:
test_node/app.js
var express = require("express");
const app = express();
app.set('port', process.env.SERVER_PORT || 443);
app.get('/', function(req, res){
res.status(200).send('OK');
});
module.exports = {
app: app
}
test_node/server.js
var https = require('https');
var fs = require('fs');
const app = require('./app');
let serverOptions = {
key: fs.readFileSync('./cert/server.key'),
cert: fs.readFileSync('./cert/server.cert')
}
const server = https.createServer(serverOptions, app)
server.listen(app.get('port'), function () {
console.log(`Express HTTPS server listening on port ${app.get('port')}`);
});
async function handleSignal(signal) {
console.log(`Received ${signal}`);
server.close();
process.exit();
}
process.on('SIGINT', handleSignal);
process.on('SIGTERM', handleSignal);
process.on('uncaughtException', handleSignal);
test_node/test/test.js
const request = require('supertest')
describe("Test the root path", () => {
let server;
beforeAll(function () {
server = require('../app');
});
afterAll(function () {
server.close();
});
test("It should respond to the GET method", async () => {
const response = await request(server).get("/");
expect(response.statusCode).toBe(200);
});
});
test_node/package.json
{
"name": "test_node",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"test": "jest"
},
"author": "",
"license": "ISC",
"devDependencies": {
"jest": "^26.6.3",
"supertest": "^6.1.3"
},
"dependencies": {
"express": "^4.17.1"
}
}
The error I get when I test the above code with jest (jest --runInBand test.js):
TypeError: app.address is not a function
at Test.Object.<anonymous>.Test.serverAddress (C:\code\test_node\node_modules\supertest\lib\test.js:57:18)
at new Test (C:\code\test_node\node_modules\supertest\lib\test.js:38:12)
at Object.get (C:\code\test_node\node_modules\supertest\index.js:27:14)
at Object.<anonymous> (C:\code\test_node\test\test.js:13:48)
at Object.asyncJestTest (C:\code\test_node\node_modules\jest-jasmine2\build\jasmineAsyncInstall.js:106:37)
at C:\code\test_node\node_modules\jest-jasmine2\build\queueRunner.js:45:12
at new Promise (<anonymous>)
at mapper (C:\code\test_node\node_modules\jest-jasmine2\build\queueRunner.js:28:19)
at C:\code\test_node\node_modules\jest-jasmine2\build\queueRunner.js:75:41
This is obviously a stripped down version of my code. I also create MongoDB connections at start, but I removed them for simplicity. Ideally I want to use async/await instead of promises for creating my server (and MongoDB connections) before my tests start. I also need to close those connections after tests end or fail. In your answer you can safely assume I'm JS beginner :).
Additional info
I'm using node '14.15.4' on Windows 10 x64. Webstorm IDE.
Tried various combinations of the following:
combining app and server in one file (see below)
creating the server in a separate function and exporting it
using mocha/chai instead of jest
testing a stripped down version of the app
Errors I get depending on the combinations I tried:
TypeError: app.address is not a function
TypeError: app.get is not a function
EADDRINUSE: address already in use ::::443
various other errors with timeouts, wrong arguments, etc.
Relevant topics that didn't help (or I overlooked something):
Simple node http server unit test
Is it possible to create an Express.js server in my Jest test suite?
TypeError: app.get is not a function
Mocha API Testing: getting 'TypeError: app.address is not a function'
Getting "TypeError: "listener" argument must be a function" in Node.Js
Jest/Supertest errors with TypeError: app.address is not a function
https://blog.campvanilla.com/jest-expressjs-and-the-eaddrinuse-error-bac39356c33a
https://glebbahmutov.com/blog/how-to-correctly-unit-test-express-server/
https://rahmanfadhil.com/test-express-with-supertest/
https://zellwk.com/blog/endpoint-testing/
https://taylor.fausak.me/2013/02/17/testing-a-node-js-http-server-with-mocha/
https://www.albertgao.xyz/2017/05/24/how-to-test-expressjs-with-jest-and-supertest/
Context
I included the server.js file above, although the test doesn't use it, because my server application should also be able to start normally when I run node server.js. With the above code it doesn't start and I get the following error:
events.js:112
throw new ERR_INVALID_ARG_TYPE('listener', 'Function', listener);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "listener" argument must be of type function. Received an instance of Object
at checkListener (events.js:112:11)
at _addListener (events.js:348:3)
at Server.addListener (events.js:406:10)
at new Server (https.js:71:10)
at Object.createServer (https.js:91:10)
at Object.<anonymous> (C:\code\test_node\server.js:9:22)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14) {
code: 'ERR_INVALID_ARG_TYPE'
}
However, if I put all code in the same app.js file and I run node app.js, then the app starts fine, although the test produces the same error.
test_node/app.js
var https = require('https');
var fs = require('fs');
var express = require("express");
var server;
const app = express();
app.set('port', process.env.SERVER_PORT || 443);
app.get('/', function(req, res){
res.status(200).send('OK');
});
async function handleSignal(signal) {
console.log(`Received ${signal}`);
server.close();
process.exit();
}
process.on('SIGINT', handleSignal);
process.on('SIGTERM', handleSignal);
process.on('uncaughtException', handleSignal);
let serverOptions = {
key: fs.readFileSync('./cert/server.key'),
cert: fs.readFileSync('./cert/server.cert')
}
server = https.createServer(serverOptions, app).listen(app.get('port'), function () {
console.log(`Express HTTPS server listening on port ${app.get('port')}`);
});
module.exports = {
app: app,
server: server
}
To clarify, my question is how to fix the error from the jest test and not about the error when I run node server.js - the latter is just for context.
As #jonrsharpe pointed out in the comments, I was assuming that with module.exports I export the app itself, but in fact I export an object containing the app. Therefore to fix the test error, I had to simply write in my test.js:
server = require('../app').app;
instead of server = require('../app');. Similarly, in server.js I had to write:
const app = require('./app').app;
This fixes both errors I mentioned in my question (TypeError: app.address is not a function).
Credits to #jonrsharpe for helping me find the solution!
I'm trying to add unit tests to my nodejs application using mocha.
I've created a dummy test endpoint '/test' which returns a string as shown below :
Test endpoint :
app.get(routeHelper.getURLPath('/test'), (req, res, next) => {
res.send('Helloo from test route !!');
next();
});
sample.test.js :
process.env.NODE_ENV = 'test';
let supertest = require("supertest");
let should = require("should");
let server = supertest.agent("http://localhost:9000");
describe('Routes', () => {
it('sample test', (done) => {
server
.get("/test")
.expect(200)
.end(function(err,res){
// console.log('***************Ressssssss******* ', res.body);
console.log('***************errrrrrrrrrrrrrr******* ', err);
res.status.should.equal(200);
res.body.error.should.equal(false);
done();
});
});
});
When I run the test, it is throwing the error shown below :
{ Error: socket hang up
at createHangUpError (_http_client.js:322:15)
at Socket.socketOnEnd (_http_client.js:425:23)
at Socket.emit (events.js:187:15)
at endReadableNT (_stream_readable.js:1094:12)
at process._tickCallback (internal/process/next_tick.js:63:19) code: 'ECONNRESET', response: undefined }
Accessing the API directly from the browser is giving the response properly. But, it's throwing this error when I run the test.
Any help to fix this will very helpful.
i have this code in express.
var express = require('express');
var http = require("http");
var https = require("https");
var app = express();
var optionsSB = {
host: 'domain.com',
path: '/wp-content/themes/domain/includes/ajax/get_properties.php'
};
var optionsLV = {
host: 'apiproperties.local',
path: '/properties/storeSB',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
https.get(optionsSB, function (https_res) {
var dataSB = "";
https_res.on("data", function (chunkSB) {
dataSB += chunkSB;
});
https_res.on("end", function () {
http.request(optionsLV, function(http_res){
var dataVL = "";
http_res.on("data", function (chunkVL) {
dataVL += chunkVL;
});
http_res.on("end", function () {
console.log(dataVL);
});
});
});
});
app.listen(3000, function () {});
I get this error
events.js:183
throw er; // Unhandled 'error' event
^
Error: connect ECONNREFUSED 127.0.0.1:80
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1182:14)
I already try some things but i dont know what is the problem, regards.
I follow some instruction from a tutorials and all works fine but that error i dont understand.
It will throw like this when you are getting an error in setting up the request with your https.get(), but you don't have any error handler to capture the error. You can supply an error handler:
https.get(...).on('error', function(err) {
// error here
console.log(err);
});
It appears that the specific error is ECONNREFUSED. It could be that the destination is not accepting your https connection or it could be that it doesn't like the way you were passing the options. Since all you have is a host and path, you can also just use the URL:
https.get("https://somedomain.com//wp-content/themes/domain/includes/ajax/get_properties.php", ...);
I am new to unit testing. I have been writing test case using mocha for Nodejs. In my case need to write test case for facebook login. I have firstly tried with facebook-mock but i was not able to complete the task.This is my test case where I have used zombie,
var chai = require('chai');
var assert = chai.assert;
var server;
var Browser = require('zombie');
describe("login using social sites",function () {
this.timeout(40000);
beforeEach(function () {
server = require('../../../server').server;
browser = new Browser({ site: 'http://localhost:3000' });
});
it("should login with facebook",function (done) {
browser.visit('/auth/facebook',function (err,brw) {
if(err){
throw err;
}
assert.equal(brw.location.pathname, '/auth/facebook/callback');
done();
});
});
afterEach(function () {
server.close();
});
});
And the server.js file is,
var express = require('./config/express');
var app = express();
var server = app.listen(3000, function () {
var port = server.address().port;
console.log('Server running at %s', port);
});
module.exports = {
app : app,
server : server
};
This is the error which i have got after executing the unit test,
1) login using social sites should login with facebook:
Uncaught TypeError: connect ECONNREFUSED 127.0.0.1:3000
at G:\Janani\Tasks\CCSProject\node_modules\zombie\lib\pipeline.js:89:15
at tryCatcher (G:\Janani\Tasks\CCSProject\node_modules\zombie\node_modules\bluebird\js\release\util.js:16:23)
at Promise._settlePromiseFromHandler (G:\Janani\Tasks\CCSProject\node_modules\zombie\node_modules\bluebird\js\release\promise.js:504:31)
at Promise._settlePromise (G:\Janani\Tasks\CCSProject\node_modules\zombie\node_modules\bluebird\js\release\promise.js:561:18)
at Promise._settlePromise0 (G:\Janani\Tasks\CCSProject\node_modules\zombie\node_modules\bluebird\js\release\promise.js:606:10)
at Promise._settlePromises (G:\Janani\Tasks\CCSProject\node_modules\zombie\node_modules\bluebird\js\release\promise.js:681:18)
at Async._drainQueue (G:\Janani\Tasks\CCSProject\node_modules\zombie\node_modules\bluebird\js\release\async.js:138:16)
at Async._drainQueues (G:\Janani\Tasks\CCSProject\node_modules\zombie\node_modules\bluebird\js\release\async.js:148:10)
at Immediate.Async.drainQueues [as _onImmediate] (G:\Janani\Tasks\CCSProject\node_modules\zombie\node_modules\bluebird\js\release\async.js:17:14)
Please anyone guide me to fix this issue. And if any other specific framework if available please guide me with that. Thanks in Advance!!
I got fixed with this issue!!!
describe("login using social sites",function () {
this.timeout(40000);
beforeEach(function () {
server = require('../../../server').server;
// browser = new Browser({ site: 'http://localhost:3000' });
});
it("should login with facebook",function (done) {
Browser.visit('http://127.0.0.1:3000/auth/facebook',function (err,brw) {
if(err){
throw err;
}
brw.fill('email','aaa#gmail.com').fill('pass', 'password')
.pressButton('login', function (err,brow) {
brw.assert.success();
done();
});
});
});
afterEach(function () {
server.close();
});
});
my file structure is like this
folder_main
-server.js
-folder_tests
--serverTest.js
var expect = require("chai").expect;
var http = require('http')
describe('/', function(){
var server;
beforeEach(function () {
server = require('../server');
});
afterEach(function () {
server.close();
});
it('should return 200 status code', function(){
http.get("http://localhost:8080", function(res) {
console.log("Got response: " + res.statusCode);
expect(res.statusCode).to.equal("This isnt even a number")
})
})
})
and server.js is
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var port = 8080;
server.listen(port);
console.log("listening on port " + port)
// router
app.get('/', function (req, res){
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("Hello World\n");
});
module.exports = server;
when I run "mocha test" from the cmd line I get
✓ should return 200 status code
1) "after each" hook
1 passing (277ms) 1 failing
1) / "after each" hook:
Uncaught Error: connect ECONNRESET
at errnoException (net.js:904:11)
at Object.afterConnect [as oncomplete] (net.js:895:19)
I am confused
The first test should fail because it compares to "This isnt even a number".
I am not sure what is happening with Uncaught Error: connect ECONNRESET
Mocha tests need to use the done() callback if you are testing asynchronous code otherwise mocha will complete before your assertions run and no failures will be detected.
it('should return 200 status code', function(done){
http.get("http://localhost:8080", function(res) {
console.log("Got response: " + res.statusCode);
expect(res.statusCode).to.equal("This isnt even a number")
done()
})
})
done is setup as the first parameter to your testing function, which you then call after your assertions. If the done function is not called, mocha will timeout the test after the default of 2 seconds.
This will probably resolve your ECONNRESET issue too as your server is not being shutdown mid test/request.
It can help to always make use of done(), even when testing synchronous code so you don't fall into this trap in the future. False positives can cause hours of trouble shooting pain.