test POST mocha - chai : return 500 - node.js

actually right now im writing API to create, get, update, and delete data using node js. my code working in a good shape.
i try it using postman to post data, it adding new data to my db.
then i want to use testing unit, named mocha - chai.
this my code :
let chai = require('chai');
let chaiHttp = require('chai-http');
let server = require('server');
let expect = require("chai").expect;
let should = require("should");
let request = require("superagent");
let util = require("util");
chai.use(chaiHttp);
describe('API Clinic Test', function() {
it('should add a SINGLE clinic on /api/v1/clinic POST', function(done) {
chai.request('http://localhost:5000')
.post('/api/v1/clinic')
.send({'clinic_name': 'Clinic Dummy', 'address': 'Bandung', 'phone':'888 888', 'fax':'888 888'})
.end(function(err, res){
expect(res.status).to.equal(200);
done();
});
});
});
if success it should return code 200.
but when i run mocha, i got this error.
i dont understad. i try using postman, it can added new data.
but why i got return 500 code when i using mocha?
is there something wrong in my codes?
please help me.
thank you.

Make your function asynchronous, testing function pretends to be executed both at the same time due to that some fail.
it('should add a SINGLE clinic on /api/v1/clinic POST', async function(done) {
await chai.request('http://localhost:5000')
.post('/api/v1/clinic')
.send({'clinic_name': 'Clinic Dummy', 'address': 'Bandung', 'phone':'888 888', 'fax':'888 888'})
.end(function(err, res) {
expect(res.status).to.equal(200);
done();
});

Related

reset a database before each test

I'm using node and supertest for a simple app. I got SQlite3 for the local test database. I did a simple test to get a super inserted into the database. I wanted to reset the database each time a test is run. I'm looking in the docs right now and can't seem to locate it. I figured I would ask here because it seems someone would most likely know the info.
const request = require('supertest');
const server = require('../server');
describe('Authentication', function() {
//database reset here
it('should create a new user /users/registration', function(done) {
request(server)
.post('/users/register')
.send({
username: 'user-name',
email: 'luser-name#gmail.com',
password: '12345'
})
.set('Accept', 'application/json')
.expect(201, done);
});
});
If you want to run any piece of code before each test, you can use beforeEach function in jest
describe('my test', () => {
beforeEach(() => {
// code to run before each test
});
test('test 1', () => {
// code
});
test('test 2', () => {
// code
});
});
So best way to do this is have some logic in your routing functions of your Api
Receive an API request
Check if ['X-MOCK-HEADER'] exists
If it does then route to the mock version of the endpoint
So your mock for create user would always return 201 OK - your mock endpoint would do something like this:
const routes = {
CREATE_USER_OK:() => { return {....} } // make sure these return proper http responses
CREATE_USER_BAD_REQUEST: () { return {...} }
}
return routes[HEADER_VALUE]()
The reason being you're testing the route not the database class in this instance, so you just want to return static data, if you wanna test something else then just change the X-MOCK-HEADER value to whatever you want and add the mock route to return the right http response/code - I'd need to know what the API code looked like to help you on the backend implementation.
If possible stay away from messing with staging databases for testing because down the road you will suffer a LOT of pain as it gradually gets filled with garbage.
Also if you're working with a front end app you can quickly prototype with static data - this is especially useful if you've got a front end team waiting for an API endpoint to say create a login screen.
There's no defined way to reset a sqlite db, just delete the db and recreate.
Sqlite: How do I reset all database tables?
I did this in the file and it works fine
const request = require('supertest');
const server = require('../server');
const knex = require('knex');
const dbConfig = require('../knexfile.js')['test'];
const db = knex(dbConfig);
describe('Authentication', () => {
beforeEach(async () => {
await db('users').truncate();
});
it('should create a new user /users/registration', function(done) {
request(server)
.post('/users/register')
.send({
username: 'user-name',
email: 'luser-name#gmail.com',
password: '12345'
})
.set('Accept', 'application/json')
.expect(201, done);
});
});

How to make a post request with node using chai in mocha and mongoDB

How to make a POST request with node using chai in mocha and mongoDB.
I have a test file that contains both my get request and post request. I the code below equals my get request that passed the 1 test I set it up for, but I'm having trouble creating my post request and I do not understand what I am supposed to do. GET request:
const chai = require('chai');
const expect = chai.expect;
const chaiHttp = require('chai-http')
chai.use(chaiHttp)
describe('site', () => { // Describe what you are testing
it('Should have home page', (done) => { // Describe
// In this case we test that the home page loads
chai.request('localhost:3000')
chai.get('/')
chai.end((err, res) => {
if (err) {
done(err)
}
res.status.should.be.equal(200)
done() // Call done if the test completed successfully.
})
})
})
This is my post/create route so far:
The pseudocode of this request is:
// How many posts are there now?
// Make a request to create another
// Check that the database has one more post in it
// Check that the response is a successful
POST Request:
const chai = require('chai')
const chaiHttp = require('chai-http')
const should = chai.should()
chai.use(chaiHttp)
const Post = require('../models/post');
describe('Posts', function() {
this.timeout(10000);
let countr;
it('should create with valid attributes at POST /posts', function(done) {
// test code
Post.find({}).then(function(error, posts) {
countr = posts.count;
let head = {
title: "post title",
url: "https://www.google.com",
summary: "post summary"
}
chai.request('localhost:3000')
chai.post('/posts').send(head)
chai.end(function(error, res) {
//console.log('success')
})
}).catch(function(error) {
done(error)
})
});
})
Any pointers on what I am doing wrong are appreciated. My OUTPUT for this error is:
1) Posts
should return a new post at POST /posts:
Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; ifreturning a Promise, ensure it resolves.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! reddit_clone#1.0.0 test: mocha
The test is timing out because the request is never sent.
Based on the docs I’m not seeing anything that suggests you can perform a post by simply passing the data into the post function. There would need to be a lot of assumptions made by the library here e.g. serialization type, headers etc.
The correct way to perform a POST request with a JSON payload would be:
chai
.request('http://localhost:3000')
.post('/posts')
.send(head)
.end((err, res) => {
...
});

How I can retaining cookies with each request

I'm new on mocha and chai.
I'm writing integration test cases into NodeJS application using mocha and chai.
I was looking for a common solution.
Here I'm explaining what I'm doing.
In short, my point is
How to retain cookies to each request
My node server is running on the separate machine on port 3000 and Test Cases will be on another machine.
This is my application directory structure
First, login API test case
let chai = require('chai');
let chaiHttp = require('chai-http');
let expect = require('chai').expect;
chai.use(chaiHttp);
let agent = chai.request.agent(endpoint);
describe('/POST login ', function () {
it(' login ', function (done) {
let req = {
'email': 'email',
'password': 'password'
};
agent
.post(login)
.send(req)
.then(function (response) {
expect(response).to.have.status(200);
done();
}).catch(function (error) {
done(error);
});
});
});
Second, to get account list
let chai = require('chai');
let chaiHttp = require("chai-http");
let expect = chai.expect;
chai.use(chaiHttp);
describe('/POST account', function () {
it(' Account List ', async function () {
let response = await chai.request(endpoint)
.post(accounts)
try {
expect(response).to.have.status(200);
} catch (error) {
throw error;
}
});
});
I've created separate files for each module.
Well,
All APIs are authenticated based on the session.
So,
Is there any way to set cookies globally on chai-http plugin?
Basically,
Login test case will set the cookie and after that, each request will carry this cookie.
Thanks

http.request callback not called in mocha and chai unit test

I'm trying to unit test a simple http REST client using mocha and chai libraries for Node.js with this code:
var chai = require('chai');
var asrt = require('chai').assert;
var client = require('../index');
describe('#Do successful', function () {
it('should pass when schema, host and port are provided', function () {
client.do('http:', 'localhost', '8080', '', function (result) {
console.log("starting assertions");
asrt.isAbove(result.items.length,0);
// ... other assertions
});
});
});
when I run the test with npm test, the test "passes" but the line that logs "starting assertions" is never printed, because the client.do function callback is never called, but I see that the server properly received the request and responded.
I'm obviously missing something, but I can't understand what in particular. Please notice that:
1) a very similar piece of code used in a non-test file produces the expected outcome (which is: the callback is called and the result data if filled with the response data).
2) Again, I'm testing a client, not a server, so I suppose I shuldn't use the done() function (but I tried as well, and didn't work).
Have you any hint on how to fix this? Thanks
Assuming that client.do is asynchronous because what you described is inline with the test executing, firing of asynchronous request, and not waiting for the response.
In this case the solution IS to use an asynchronous test with the done parameter:
var chai = require('chai');
var asrt = require('chai').assert;
var client = require('../index');
describe('#Do successful', function () {
it('should pass when schema, host and port are provided', function (done) {
client.do('http:', 'localhost', '8080', '', function (result) {
console.log("starting assertions");
asrt.isAbove(result.items.length,0);
// ... other assertions
// TEST WAITS FOR TIMEOUT OR UNTIL done() IS CALLED
done();
});
});
});

How do I simulate Strongloop's update method with Supertest/Superagent?

I'm working on some tests for strongloop/loopback APIs using supertest and mocha. One of the standard endpoints is Model/update. Update is actually a form of PersistedModel.updateAll which takes in a query and then posts to all entries that match the query. This is a picture of what a successful request looks like in the explorer:
Notice from the picture that the request URL is mainly just a query string, and that it returns 204. I know from the superagent docs that you can submit querys with a post. However I'm having a lot of trouble duplicating this with my tests.
Here are my require statements:
var request = require('supertest');
var app = require('../server');
var assert = require('chai').assert;
var chance = require('chance').Chance();
Here are my tests
describe('/api/Points/update', function(){
var updatedZip = "60000";
it('should grab a Point for a before reference', function(done) {
json('get', '/api/Points/' +addID )
.end(function(err, res) {
assert.equal(res.body.zipcode, addZip, 'unexpected value for zip');
done();
});
});
it('should update the Point w/ a new zipcode', function(done) {
var where = {"zipcode": "60035"};
var data ={"zipcode": updatedZip};
request(app)
.post('/api/Points/update')
.query({"where": {"zipcode": "60035"}})
.send({
data : data
})
.end(function(err, res) {
assert.equal(res.status, 204, 'update didnt take');
done();
});
});
it('should check to see that the Point was updated', function(done) {
json('get', '/api/Points/' +addID )
.end(function(err, res) {
assert.equal(res.body.zipcode, updatedZip, 'updated zip was not applied');
done();
});
});
The first test passes, meaning that it returned a 204 as the status of the request however it fails the second test meaning that even though it found the query acceptable it didn't actually apply the update. I've tried a number of different formulations but none of them have worked. Please let me know how I could possibly simulate this! Thanks in advance for your help!

Resources