Mocha supertest isn't POSTing data - node.js

My test looks like:
const request = require('supertest-as-promised')
const app = require('../app')
describe("Basic Authentication with JWT", () => {
it('Should login properly', function () {
return request(app)
.post('/login')
.field('name', 'myname')
.field('password', 'password')
.expect(200)
});
})
In my app, I have:
app.post("/login", (req, res) => {
console.log(req.body)
When I run the app normally, it gets the information properly. When I run the test, it shows as {}
What gives?

Try something like that:
describe("Basic Authentication with JWT", () => {
it('Should login properly', function () {
request(app)
.post('/login')
.send({
name: "test_name",
password: "test_password"
})
.then((res) => {
res.statusCode.should.eql(200);
done();
})
.catch(done)
});
})

Related

Node.js/express integration test with jest/supertest suitable for automated tests

Given a nodejs/express web api application which works with MySQL, MongoDB and calls some external apis and services, we want to add testing with jest and supertest.
Now, what are the ways for integration testing, calling apis which includes all code from controller to database? in-memory databases, mocking and dedicated database for testing are options.
One important use case is automated tests under CI/CD tools.
Any help is highly appreciated.
I can share my sample test file for you
/* eslint-disable no-undef */
const dotenv = require('dotenv');
const mongoose = require('mongoose');
const request = require('supertest');
const app = require('../app');
dotenv.config({ path: '.env.test' });
describe('Test Armature Type', () => {
jest.setTimeout(20 * 1000);
let user = null;
let armatureType = null;
test('login Super Admin', async () => {
await request(app)
.post('/api/v1/auth/login')
.send({
email: process.env.SUPER_ADMIN_EMAIL,
password: process.env.SUPER_ADMIN_PASSWORD
})
.then((resLogin) => {
expect(resLogin.statusCode).toBe(200);
const bodyLogin = JSON.parse(resLogin.res.text);
user = bodyLogin.data;
})
.catch((err) => {
console.log(err.toString());
});
});
test('create Armature Type', async () => {
await request(app)
.post('/api/v1/armature/type/create')
.send({
name: 'TEST'
})
.set({ Authorization: `Bearer ${user.access_token}` })
.then((resCreate) => {
expect(resCreate.statusCode).toBe(200);
const bodyResCreate = JSON.parse(resCreate.res.text);
armatureType = bodyResCreate.data;
})
.catch((err) => {
console.log(err.toString());
});
});
test('edit Armature Type', async () => {
await request(app)
.post('/api/v1/armature/type/edit')
.send({
armatureTypeId: armatureType._id,
name: 'TEST NEW'
})
.set({ Authorization: `Bearer ${user.access_token}` })
.then((resEdit) => {
expect(resEdit.statusCode).toBe(200);
})
.catch((err) => {
console.log(err.toString());
});
});
test('delete Armature Type', async () => {
await request(app)
.post('/api/v1/armature/type/delete')
.send({
armatureTypeId: armatureType._id
})
.set({ Authorization: `Bearer ${user.access_token}` })
.then((resDelete) => {
expect(resDelete.statusCode).toBe(200);
})
.catch((err) => {
console.log(err.toString());
});
});
beforeEach(async () => {
await mongoose.connect(process.env.MONGO_URI);
});
afterEach(async () => {
await mongoose.connection.close();
});
});

Jest error MongoServerError: E11000 duplicate key error collection

I'm trying to learn testing with jest and supertest. I have this simple API:
app.get("/", (req, res) => {
res.json({ name: "bob" });
});
app.delete("/delete", async (req, res) => {
const result = await Todos.deleteOne({ _id: req.body.id });
res.send(result);
});
app.post("/add", (req, res) => {
const { item, status } = req.body;
const todo = new Todos({
item,
});
todo.save();
res.send(todo);
});
They all work. I also have these tests **which when individually run they all pass, but when I run them together the delete fails.
My logic is, when adding a post, I'm passing the id of the created post to the test so that the delete test can use
const request = require("supertest");
const app = require("../server");
describe("testing Todos API", () => {
let payload = { id: "6156c95c9ecf28237844489b" };
let item = { item: "test" };
it("get", (done) => {
request(app)
.get("/")
.expect(200)
.end((err, res) => {
expect(res.body).toEqual({ name: "bob" });
expect(res.body.name).toEqual("bob");
done();
});
});
it("post", (done) => {
request(app)
.post("/add")
.send(item)
.expect(200)
.end((err, res) => {
payload.id = res.body._id;
expect(res.body.item).toEqual(item.item);
done();
});
});
it("delete", (done) => {
request(app)
.delete("/delete")
.send(payload)
.end((err, res) => {
console.log(res.body);
expect(res.body.deletedCount).toEqual(1);
done();
});
});
});
But I get the error of error MongoServerError: E11000 duplicate key error collection and deletedCount is 0

mocha, chai testing for post in nodejs

I am new to unit testing in node.js with sequelize.js. I followed this tutorial to implement the api. It is working fine and I need to test it for unit testing.
First I tried to test post operation for User class. Following code is to be tested using mocha.
// create a user
app.post('/api/users', (req, res) => {
User.create(req.body)
.then(user => res.json(user))
})
My attempt is as below.
var index = require('../index');
describe('POST testing on user', function () {
it('should add a row', function (done) {
index.post('/api/users').send({ 'name': 'he' })
.end(function (err, res) {
chai.expect(res.status).to.equal(200);
done();
})
});
});
Then it will give this error saying index.post is not a function. Where should I get wrong and how can I correct it to execute the test case.
Your logic is quite wrong. It should be:
describe('/POST Create User', () => {
it('Create User Testing', (done) => {
let user = {
'name': 'he'
}
chai.request('http://localhost:3000')
.post('/api/users')
.send(user)
.end((err, res) => {
});
});
});
});

Chai assertion for expressjs token-based app

I'm writting tests for an expressjs token-based app, however I read the chai doc and find only cookie based auth. With an workaround the test passed with the code above, however I need the token to be used in others it statements. Any tips are welcome. I'm using mochajs to run tests.
var chai = require('chai');
var chaiHttp = require('chai-http');
var mongoose = require('mongoose');
var server = require('../app');
var Dish = require('../models/dishes');
var should = chai.should();
chai.use(chaiHttp);
describe('Users', function() {
it('should return success on /login POST', function(done) {
var agent = chai.request.agent(server)
agent
.post('/users/login')
.send({"username": "admin", "password": "password"})
.then(function(res) {
res.should.have.cookie('token');
return agent.get('/users')
.then(function(res) {
res.should.have.status(200);
});
});
done();
});
it('should return success on /users GET', function(done) {
chai.request(server)
.get('/users')
.end(function(err, res) {
res.should.have.status(200);
done();
});
});
});
describe('Dishes', function() {
it('should list ALL dishes on /dishes GET', function(done) {
chai.request(server)
.get('/dishes')
.end(function(err, res) {
res.should.have.status(200);
done();
});
});
it('should list a SINGLE dish on /dish/<id> GET');
it('should add a SINGLE dish on /dishes POST');
it('should update a SINGLE dish on /dish/<id> PUT');
it('should delete a SINGLE dish on /dish/<id> DELETE');
});
You can start your test by before, and then get you token
let token = '';
describe('Users', () => {
before((done) => {
const userCredentials = {
username: 'admin',
password: 'password'
};
chai.request(server)
.post('/api/v1/auth')
.send(userCredentials)
.end((err, res) => {
console.log('res', res.body.data.customer.token);
token = `Bearer ${res.body.data.customer.token}`;
done();
});
})
// Your test
})

Scopes & Closures in Mocha/Chai Assertions

I'm writing some tests for an express app and I am wondering how to properly access a variable in one assertion block from another. The variable I am trying to access is this.token = res.body.token
Whenever I try to access it, it comes up undefined (other than when accessing it within the beforeEach block). How can I access this variable? I need to use the token to set the headers in my test for my POST request.
Code:
describe('CRUD: tests the GET & POST routes', () => {
beforeEach(done => {
chai.request('localhost:3000')
.post('/app/signup')
.send({ email: 'meow#test.com', password: 'testpass' })
.end((err, res) => {
if (err) return console.log(err);
this.token = res.body.token; // this variable holds a token when accessed within this scope (tested it with node debugger)
done();
});
});
it('should create with a new cat with a POST request', (done) => {
chai.request('localhost:3000')
.post('/app/cats')
.set('token', this.token) // when accessed here, it is undefined...
.send({ username: 'cat_user' })
.end((err, res) => {
expect(err).to.eql(null);
expect(res).to.have.status(200);
expect(res.body.name).to.eql('test cat');
expect(res.body).to.have.property('_id');
done();
});
});
EDIT: Here is a screenshot of my terminal in node debug mode. As you can see, when it hits the first debugger break and _token is accessed, it contains the token. In the next debugger break, however, it comes up empty... (maybe that means something else in the debugger?)
You can move your variable to the scope of your describe.
describe('CRUD: tests the GET & POST routes', () => {
let _token;
beforeEach(done => {
chai.request('localhost:3000')
.post('/app/signup')
.send({ email: 'meow#test.com', password: 'testpass' })
.end((err, res) => {
if (err) return console.log(err);
_token = res.body.token; // this variable holds a token when accessed within this scope (tested it with node debugger)
done();
});
});
it('should create with a new cat with a POST request', (done) => {
chai.request('localhost:3000')
.post('/app/cats')
.set('token', _token) // when accessed here, it is undefined...
.send({ username: 'cat_user' })
.end((err, res) => {
expect(err).to.eql(null);
expect(res).to.have.status(200);
expect(res.body.name).to.eql('test cat');
expect(res.body).to.have.property('_id');
done();
});
});
You should read this to understand this: http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/

Resources