do teste de unidade ao de
integração
Teste de unidade
→ mocha ( $ npm i -D mocha )
→ chai ( $ npm i -D chai )
→ sinon ( $ npm i -D sinon )
$ mkdir -p nodejs-tests/test ; cd nodejs-tests
$ npm init -y
$ touch index.js test/index.test.js
$ npm i -D mocha chai sinon
index.js
exports.sum = (x, y) => x + y;
index.test.js
const assert = require('assert');
const { sum } = require('../index');
describe('Index', () => {
describe('sum()', () => {
it('should return the sum of 2 + 2 that equals 4', () => {
const result = sum(2, 2);
assert.deepEqual(result, 4);
});
});
});
package.json
"scripts": {
"test": "mocha test/**/*.test.js"
}
$ npm test
Index
sum()
✓ should return the sum of 2 + 2 that equals 4
1 passing (13ms)
index.test.js
const { expect } = require('chai');
const { sum } = require('../index');
describe('Index', () => {
describe('sum()', () => {
it('should return the sum of 2 + 2 that equals 4', () => {
expect(sum(2, 2)).to.be.deep.equal(4);
});
});
});
Chai
const should = require('chai').should();
foo.should.be.a('string');
foo.should.equal('bar');
foo.should.have.lengthOf(3);
tea.should.have.property('flavors')
.with.lengthOf(3);
const { assert } = require('chai');
assert.typeOf(foo, 'string');
assert.equal(foo, 'bar');
assert.lengthOf(foo, 3)
assert.property(tea, 'flavors');
assert.lengthOf(tea.flavors, 3);
Should Assert
class UserService {
constructor(Database) {
this.Database = Database;
}
async findAll() {
try {
const users = await this.Database.findAll();
return users;
} catch (error) {
console.log('Error on find users from database', error);
}
}
}
module.exports = UserService;
const UserService = require('../src/users/user.service');
const { expectedUser } = require('./fixtures/user.json');
describe('UserService', () => {
describe('findAll()', () => {
it('should return all users', async() => {
const fakeDatabase = {
async findAll() {
return [expectedUser];
}
}
const userService = new UserService(fakeDatabase);
const users = await userService.findAll();
expect(users).to.be.eql([expectedUser]);
});
});
});
class UserService {
constructor(Database) {
this.Database = Database;
}
async create(user) {
try {
await this.Database.create(user);
} catch(error) {
console.log('Error on create a new user', error);
}
}
// other methods...
}
module.exports = UserService;
const sinon = require('sinon');
const UserService = require('../src/users/user.service');
const { newUser } = require('./fixtures/user.json');
describe('UserService', () => {
describe('create()', () => {
it('should create a new user', () => {
const fakeDatabase = {
create(user) { }
};
const createSpy = sinon.spy(fakeDatabase, 'create');
const userService = new UserService(fakeDatabase);
userService.create(newUser);
sinon.assert.calledOnce(createSpy);
sinon.assert.calledWith(createSpy, newUser);
createSpy.restore();
});
});
});
const axios = require('axios');
class OrderService {
constructor() {}
async findByUserId(userId) {
try {
const response = await axios.get(`https://api/v1/orders?userId=${userId}`);
return response.data.orders;
} catch(error) {
console.log(`Error on find orders`, error);
}
}
}
module.exports = OrderService;
const sinon = require('sinon');
const axios = require('axios');
const OrderService = require('../src/orders/order.service');
const { orders } = require('./fixtures/orders.json');
describe('OrderService', () => {
describe(`findByUserId(1)`, () => {
it('should return orders from userId 1', async() => {
const userId = 1;
const orderService = new OrderService();
const ordersResponse = { data: { orders: orders } };
const getStub = sinon.stub(axios, 'get');
getStub
.withArgs(`https://api/v1/orders?userId=${userId}`)
.returns(Promise.resolve(ordersResponse));
const response = await orderService.findByUserId(userId);
expect(response).to.be.eql(orders);
getStub.restore();
});
});
});
Teste de integração
→ mocha ( $ npm i -D mocha )
→ chai ( $ npm i -D chai )
→ chai-http ( $ npm i -D chai-http )
→ nock ( $ npm i -D nock )
app.js
const express = require('express');
const bodyParser = require('body-parser');
const userRoutes = require('./users/user.routes');
const database = require('./database');
const app = express();
app.use(bodyParser.json());
app.database = database();
userRoutes(app);
module.exports = app;
helpers.js
const chai = require('chai');
const chaiHttp = require('chai-http');
const app = require('../../src/app');
chai.use(chaiHttp);
global.request = chai.request(app);
global.UserModel = app.database.models.Users;
global.expect = chai.expect;
user.routes.js
const { CREATED } = require('http-status');
const UserService = require('./user.service');
module.exports = (app) => {
const userService = new UserService(app.database.models.Users);
app.post('/users', (req, res) => {
return userService.create(req.body)
.then(() => res.sendStatus(CREATED));
});
app.get('/users', (req, res) => {
return userService.findAll()
.then(users => res.json({ users }));
});
}
const { CREATED } = require('http-status');
const { newUser } = require('./fixtures/user.json');
describe('User routes', () => {
beforeEach(() => UserModel.destroy({ where: {} }));
describe('POST /users', () => {
it('should create a new user', async() => {
const response = await request.post('/users').send(newUser);
const resultSet = await UserModel.findById(newUser.id);
const userCreated = resultSet.toJSON();
expect(response).to.have.status(CREATED);
expect(userCreated).to.be.eql(newUser);
});
});
});
"scripts": {
"test:unit": "mocha --require test/unit/helpers.js test/unit/**/*.test.js",
"test:integration": "mocha --require test/integration/helpers.js test/integration/**/*.test.js --exit",
}
const { CREATED, OK } = require('http-status');
const { newUser, defaultUser } = require('./fixtures/user.json');
describe('User routes', () => {
beforeEach(() => {
return UserModel
.destroy({ where: {} })
.then(() => UserModel.create(defaultUser));
});
describe('GET /users', () => {
it('should return all users', async() => {
const response = await request.get('/users');
expect(response).to.have.status(OK);
expect(response.body.users).to.be.eql([defaultUser]);
});
});
});
const OrderService = require('./order.service');
module.exports = (app) => {
const orderService = new OrderService();
app.get('/orders', (req, res) => {
return orderService.findByUserId(req.query.userId)
.then(orders => res.json({ orders }));
});
}
const { OK } = require('http-status');
const { orders } = require('./fixtures/order.json');
const userId = 1;
describe('Order routes', () => {
beforeEach(() => {
nock('https://api')
.get(`/v1/orders?userId=${userId}`)
.reply(OK, { orders });
});
it(`GET /orders?userId=${userId}`, async() => {
const response = await
request.get(`/orders?userId=${userId}`);
expect(response).to.have.status(OK);
expect(response.body).to.be.eql({ orders });
});
});
Obrigado!
Vinícius Pretto
Software Developer at
vini.prettodasilva@gmail.com
https://github.com/vinicius-pretto/nodejs-automation-tests

Nodejs do teste de unidade ao de integração

  • 1.
    do teste deunidade ao de integração
  • 3.
    Teste de unidade →mocha ( $ npm i -D mocha ) → chai ( $ npm i -D chai ) → sinon ( $ npm i -D sinon )
  • 4.
    $ mkdir -pnodejs-tests/test ; cd nodejs-tests $ npm init -y $ touch index.js test/index.test.js $ npm i -D mocha chai sinon
  • 5.
  • 6.
    index.test.js const assert =require('assert'); const { sum } = require('../index'); describe('Index', () => { describe('sum()', () => { it('should return the sum of 2 + 2 that equals 4', () => { const result = sum(2, 2); assert.deepEqual(result, 4); }); }); });
  • 7.
  • 8.
    $ npm test Index sum() ✓should return the sum of 2 + 2 that equals 4 1 passing (13ms)
  • 9.
    index.test.js const { expect} = require('chai'); const { sum } = require('../index'); describe('Index', () => { describe('sum()', () => { it('should return the sum of 2 + 2 that equals 4', () => { expect(sum(2, 2)).to.be.deep.equal(4); }); }); });
  • 10.
    Chai const should =require('chai').should(); foo.should.be.a('string'); foo.should.equal('bar'); foo.should.have.lengthOf(3); tea.should.have.property('flavors') .with.lengthOf(3); const { assert } = require('chai'); assert.typeOf(foo, 'string'); assert.equal(foo, 'bar'); assert.lengthOf(foo, 3) assert.property(tea, 'flavors'); assert.lengthOf(tea.flavors, 3); Should Assert
  • 11.
    class UserService { constructor(Database){ this.Database = Database; } async findAll() { try { const users = await this.Database.findAll(); return users; } catch (error) { console.log('Error on find users from database', error); } } } module.exports = UserService;
  • 12.
    const UserService =require('../src/users/user.service'); const { expectedUser } = require('./fixtures/user.json'); describe('UserService', () => { describe('findAll()', () => { it('should return all users', async() => { const fakeDatabase = { async findAll() { return [expectedUser]; } } const userService = new UserService(fakeDatabase); const users = await userService.findAll(); expect(users).to.be.eql([expectedUser]); }); }); });
  • 13.
    class UserService { constructor(Database){ this.Database = Database; } async create(user) { try { await this.Database.create(user); } catch(error) { console.log('Error on create a new user', error); } } // other methods... } module.exports = UserService;
  • 14.
    const sinon =require('sinon'); const UserService = require('../src/users/user.service'); const { newUser } = require('./fixtures/user.json'); describe('UserService', () => { describe('create()', () => { it('should create a new user', () => { const fakeDatabase = { create(user) { } }; const createSpy = sinon.spy(fakeDatabase, 'create'); const userService = new UserService(fakeDatabase); userService.create(newUser); sinon.assert.calledOnce(createSpy); sinon.assert.calledWith(createSpy, newUser); createSpy.restore(); }); }); });
  • 15.
    const axios =require('axios'); class OrderService { constructor() {} async findByUserId(userId) { try { const response = await axios.get(`https://api/v1/orders?userId=${userId}`); return response.data.orders; } catch(error) { console.log(`Error on find orders`, error); } } } module.exports = OrderService;
  • 16.
    const sinon =require('sinon'); const axios = require('axios'); const OrderService = require('../src/orders/order.service'); const { orders } = require('./fixtures/orders.json'); describe('OrderService', () => { describe(`findByUserId(1)`, () => { it('should return orders from userId 1', async() => { const userId = 1; const orderService = new OrderService(); const ordersResponse = { data: { orders: orders } }; const getStub = sinon.stub(axios, 'get'); getStub .withArgs(`https://api/v1/orders?userId=${userId}`) .returns(Promise.resolve(ordersResponse)); const response = await orderService.findByUserId(userId); expect(response).to.be.eql(orders); getStub.restore(); }); }); });
  • 17.
    Teste de integração →mocha ( $ npm i -D mocha ) → chai ( $ npm i -D chai ) → chai-http ( $ npm i -D chai-http ) → nock ( $ npm i -D nock )
  • 18.
    app.js const express =require('express'); const bodyParser = require('body-parser'); const userRoutes = require('./users/user.routes'); const database = require('./database'); const app = express(); app.use(bodyParser.json()); app.database = database(); userRoutes(app); module.exports = app;
  • 20.
    helpers.js const chai =require('chai'); const chaiHttp = require('chai-http'); const app = require('../../src/app'); chai.use(chaiHttp); global.request = chai.request(app); global.UserModel = app.database.models.Users; global.expect = chai.expect;
  • 21.
    user.routes.js const { CREATED} = require('http-status'); const UserService = require('./user.service'); module.exports = (app) => { const userService = new UserService(app.database.models.Users); app.post('/users', (req, res) => { return userService.create(req.body) .then(() => res.sendStatus(CREATED)); }); app.get('/users', (req, res) => { return userService.findAll() .then(users => res.json({ users })); }); }
  • 22.
    const { CREATED} = require('http-status'); const { newUser } = require('./fixtures/user.json'); describe('User routes', () => { beforeEach(() => UserModel.destroy({ where: {} })); describe('POST /users', () => { it('should create a new user', async() => { const response = await request.post('/users').send(newUser); const resultSet = await UserModel.findById(newUser.id); const userCreated = resultSet.toJSON(); expect(response).to.have.status(CREATED); expect(userCreated).to.be.eql(newUser); }); }); });
  • 23.
    "scripts": { "test:unit": "mocha--require test/unit/helpers.js test/unit/**/*.test.js", "test:integration": "mocha --require test/integration/helpers.js test/integration/**/*.test.js --exit", }
  • 24.
    const { CREATED,OK } = require('http-status'); const { newUser, defaultUser } = require('./fixtures/user.json'); describe('User routes', () => { beforeEach(() => { return UserModel .destroy({ where: {} }) .then(() => UserModel.create(defaultUser)); }); describe('GET /users', () => { it('should return all users', async() => { const response = await request.get('/users'); expect(response).to.have.status(OK); expect(response.body.users).to.be.eql([defaultUser]); }); }); });
  • 25.
    const OrderService =require('./order.service'); module.exports = (app) => { const orderService = new OrderService(); app.get('/orders', (req, res) => { return orderService.findByUserId(req.query.userId) .then(orders => res.json({ orders })); }); }
  • 26.
    const { OK} = require('http-status'); const { orders } = require('./fixtures/order.json'); const userId = 1; describe('Order routes', () => { beforeEach(() => { nock('https://api') .get(`/v1/orders?userId=${userId}`) .reply(OK, { orders }); }); it(`GET /orders?userId=${userId}`, async() => { const response = await request.get(`/orders?userId=${userId}`); expect(response).to.have.status(OK); expect(response.body).to.be.eql({ orders }); }); });
  • 27.
    Obrigado! Vinícius Pretto Software Developerat vini.prettodasilva@gmail.com https://github.com/vinicius-pretto/nodejs-automation-tests