I am writing tests for an API built with Node and Express. I am trying to test the registration route using mocha and chai. But the test data for registration inserts into the database, which I don't want.
Is it possible to test registration and make sure it works without the dummy data inserting into the database?
Or better, how can I hook up the testing to a different database?
Thank you.
Just incase, here is the code for my test
describe('AUTH ROUTES', () => {
describe('POST /api/v1/auth/register', () => {
const correctUser = {
firstName: 'test',
lastName: 'test',
email: 'test#test.com',
password: '111'
};
const wrongUser = {
lastName: 'test',
password: '111'
};
it('It should REGISTER a user when complete detail is received', (done) => {
chai
.request(server)
.post('/api/v1/auth/register')
.send(correctUser)
.end((err, res) => {
res.should.have.status(SUCCESS_CODE);
res.body.should.be.a('object');
res.body.should.have.property('success').eq(true);
done();
});
});
it('It should NOT REGISTER a user when incomplete detail is received', (done) => {
chai
.request(server)
.post('/api/v1/auth/register')
.send(wrongUser)
.end((err, res) => {
res.should.have.status(BAD_REQUEST.code);
res.body.should.be.a('object');
res.body.should.have.property('errors');
done();
});
});
});
You should use afterEach function to drop the table after you run your beforeEach test.
You can stub every response given by your controller.
Related
How I create a reusable function which gives me a JWT token, so I can execute my test cases in which token is required without calling the login function again and again in each test case file
account.js
describe("Account", () => {
var token;
describe("/POST Login", () => {
it("it should gives the token", (done) => {
chai.request(server)
.post('api/v1/account')
.set('Accept', 'application/json')
.send({ "email": "john#gmail.com", "password": "123456" })
.end((err, res) => {
res.should.have.status(200);
res.body.should.have.property("token");
token = res.body.token //----------------TOKEN SET
done();
});
});
});
describe("/GET account", () => {
it("it should get the user account", (done) => {
chai.request(server)
.get('api/v1/account')
.set('x-auth-token', token)
.end((err, res) => {
res.should.have.status(200);
done();
});
});
});
});
category
describe("Category", () => {
var token;
//Login function duplicate in both the files
describe("/POST Login", () => {
it("it should gives the token", (done) => {
chai.request(server)
.post('api/v1/account')
.set('Accept', 'application/json')
.send({ "email": "john#gmail.com", "password": "123456" })
.end((err, res) => {
res.should.have.status(200);
res.body.should.have.property("token");
token = res.body.token //----------------TOKEN SET
done();
});
});
});
describe("/GET category", () => {
it("it should get the user account", (done) => {
chai.request(server)
.get('api/v1/account')
.set('x-auth-token', token)
.end((err, res) => {
res.should.have.status(200);
done();
});
});
});
});
I want to get the token from other file and used in different cases. What is the best approach todo this?
I'm basing my response on the fact that you have mentioned unit tests. Usually, with a unit test, you're testing a small piece of functionality. This means, that you want to test a small piece of logic within a bigger component/piece of logic and you are not interested in testing other components (like for example in your case testing your API. What you usually want to test is how your logic should behave in the case you will receive a 200 success response from the API or what happens with your logic if you receive a 400 or 500. I would recommend to mock your API calls for your testing by using a library like nock:
https://www.npmjs.com/package/nock
The way that you are trying to implement it it might be a bit more complicated. If you want to do this kind of testing I wouldn't pick jest/mocha as test runners. I would prepare a postman collection (probably you already have that) and then I would utilise newman to run my collection and actually do the integration testing that you want. You can read further here: Running collections on the command line with Newman
There are different approaches as well, but the one above can be a good one.
Use a before hook that would always login users and generates a token that can be used in your new test file.
let token;
before('Login user', async () => {
const response = await chai.request(server)
.post('api/v1/account')
.set('Accept', 'application/json')
.send({ "email": "john#gmail.com", "password": "123456" })
token = res.body.token;
});
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) => {
});
});
});
});
I am trying to testing a node.js api with mocha and chai assertion.
My problem is that I always get a 'passed result'.
The test:
describe('TESTING /register', () => {
it('Should create a new account for chai-testing:chai-testing', () => {
let user = {
pseudo: "chai-testing",
mail: "chai#chai.com",
password: "chai-testing"
};
chai.request(server)
.post('/register')
.send(user)
.end((err, resp) => {
console.log(resp.body);
resp.body.should.have.property('success').eql(true);
done();
});
});
});
And the console output :
TESTING /register
✓ Should create a new account for chai-testing:chai-testing
chai-testing chai#chai.com chai-testing
1 passing (51ms)
{ favoris: [],
_id: 5abf6b5502c0f910439fec32,
pseudo: 'chai-testing',
mail: 'chai#chai.com',
password: '$2a$10$BPzQfp3wiDxU3mwgeXkG8Oh.B1ET8wTt5kg12oBwQ0obUxAyZQdLu',
admin: false,
__v: 0 }
POST /register 200 281.742 ms - 51
{ **success: false**, message: 'pseudo already taken' }
What I did do wrong in my test?
put there two assertion instead of this :
describe('TESTING /register', () => {
it('Should create a new account for chai-testing:chai-testing', () => {
let user = {
pseudo: "chai-testing",
mail: "chai#chai.com",
password: "chai-testing"
};
chai.request(server)
.post('/register')
.send(user)
.end((err, resp) => {
console.log(resp.body);
// if the resp has an attribute success then this
// assertion is true ( .eql(true) )
// that's why you get the test always passing
resp.body.should.have.property('success');
resp.body.success.should.eql(true);
done();
});
});
});
I am using Mocha and Chai to test my Node/Express API, and I can't figure out why the test is not reaching the .end()
Here is the test:
it('should authenticate successfully with user credentials', function (done) {
agent
.post('/login')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({ 'username': 'username', 'password': 'password'})
.end(function (err, res) {
console.log(res);
console.log('***************************Authenticated*********************************************');
expect(res).to.have.status(200);
});
done();
});
And here is the route I am hitting:
app.post('/login', passport.authenticate('ldapauth', { successRedirect: '/' }));
I figure my problem may be with the fact that there is no formal response, but rather a redirect, but I am not sure how to handle it.
The solution ended up being to move the done() callback into my .end() method. Thanks #robertklep
If you are testing async methods int mocha, you should call call method in callback function as below.
it('should authenticate successfully with user credentials', function (done) {
agent
.post('/login')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({ 'username': 'username', 'password': 'password'})
.end(function (err, res) {
console.log(res);
console.log('***************************Authenticated*********************************************');
expect(res).to.have.status(200);
done();
});
});
I have the same problem with chai request. I want to wait for .end callback before going to another function. but I can't use mocha because I'm using cucumber. how can I wait for chai .end callback?
in fact, I want to log (1) first but it does not work properly
When('I submit with method {string}:', function (string, docString) {
chai.request(app)
.post(endpoint)
.send(docString)
.end(function (err, res) {
console.log(1)
response = res
})
});
Then('I recieved ok', function () {
console.log(2)
// expect(response.status).to.deep.equal(200)
});
I write test for my sails application, but have some problem in controller. When user signup I check for duplication, if yes - render form with error, if no - render form with success message. So can anyone know how to test it right? Or maybe you can suggest better code structure, thanks a lot.
Controller :
User.findOne({ email: req.body.email }, function(err, user) {
if(err) return res.json(err)
if(!user) {
User.create({email:req.body.email, password:req.body.password}).exec(function createCB(err, user){
if(err) return res.json(err);
res.view('signup', { message: 'Done, user created'})
})
} else
res.view('signup', { message: 'User already exist'})
})
Test :
it('should show error if duplicated user - TODO', function (done) {
request(sails.hooks.http.app)
.post('/signup')
.send({ email: 'test#test.te', password: 'test' })
.expect(200)
.end(done)
})
So question is, how can I test res.view?
I usually use simple request at my test if I want to test my view. Like this:
it('able to test view', function(done) {
require('request-promise')('http://localhost:1337/')
.then(function(res) {
res.should.contains('Done, user created');
done();
})
.catch(done);
});
It will check the whole body, is there any match string that we provide. Remember to do npm install request-promise --save-dev first (or any relevant library that can make request).
Or you can use supertest library as mentioned by #Yann like this
it('should be able to test view', function(done) {
require('supertest')
.agent(sails.hooks.http.app)
.post('/signup')
.send({ email: 'test#test.te', password: 'test' })
.expect(200)
.end(function(err, res) {
should.not.exist(err);
res.should.contains('Done, user created');
return done();
});
});
You can use a library like supertest to do an HTTP request:
it('should be able to test view', function(done) {
require('supertest')
.agent(sails.hooks.http.app)
.post('/signup')
.send({ email: 'test#test.te', password: 'test' })
.expect(200)
.end(function(err, res) {
should.not.exist(err);
res.should.contains('Done, user created');
return done();
});
});