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) => {
});
});
});
});
Related
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.
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;
});
Hey I want return an array in integration tests,
I have a function in which tables are retrieved. Function expect object req.user._id, so I create it, next I create integration test, but when i run I have return empty object, could someone tell me what I have to do to get returned array?
function :
.get('/boards-list', function (req, res) {
Board.find({ 'users': req.user._id })
.then((board) => {
res.json(board);
})
.catch((err) => {
res.status(404).json('Nie można pobrać tablic.')
})
})
mocha :
describe('/boards-list', () => {
it('it should GET all the boards', (done) => {
var req = {};
req.user = {};
req.user._id = "ObjectId('5a8db5d449c0572dbc60548c')";
chai.request(server)
.get('/boards-list')
.send(req)
.end((err, res) => {
console.log(res.body);
// res.should.have.status(200);
// res.body.should.be.a('array');
// res.body.length.should.be.eql(0);
done();
});
});
});
I think the problem is with the id you are passing:
req.user._id = "ObjectId('5a8db5d449c0572dbc60548c')";
Try to pass it like this:
req.user._id = "5a8db5d449c0572dbc60548c";
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)
});
})
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/