SlideShare a Scribd company logo
1 of 27
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

More Related Content

What's hot

AngularJS Routing
AngularJS RoutingAngularJS Routing
AngularJS RoutingEyal Vardi
 
06 jQuery #burningkeyboards
06 jQuery  #burningkeyboards06 jQuery  #burningkeyboards
06 jQuery #burningkeyboardsDenis Ristic
 
AngularJS Compile Process
AngularJS Compile ProcessAngularJS Compile Process
AngularJS Compile ProcessEyal Vardi
 
05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboardsDenis Ristic
 
第4回 g* ワークショップ はじめてみよう! Grailsプラグイン
第4回 g* ワークショップ はじめてみよう! Grailsプラグイン第4回 g* ワークショップ はじめてみよう! Grailsプラグイン
第4回 g* ワークショップ はじめてみよう! GrailsプラグインTsuyoshi Yamamoto
 
Cервер на Go для мобильной стратегии
Cервер на Go для мобильной стратегииCервер на Go для мобильной стратегии
Cервер на Go для мобильной стратегииArtem Kovardin
 
The next step, part 2
The next step, part 2The next step, part 2
The next step, part 2Pat Cavit
 
Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0Eyal Vardi
 
jQuery: out with the old, in with the new
jQuery: out with the old, in with the newjQuery: out with the old, in with the new
jQuery: out with the old, in with the newRemy Sharp
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performanceYehuda Katz
 
Performance Optimization In Angular 2
Performance Optimization In Angular 2Performance Optimization In Angular 2
Performance Optimization In Angular 2Eyal Vardi
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js FundamentalsMark
 
Understanding Functions and "this" in the World of ES2017+
Understanding Functions and "this" in the World of ES2017+Understanding Functions and "this" in the World of ES2017+
Understanding Functions and "this" in the World of ES2017+Bryan Hughes
 
AngularJS: what is underneath the hood
AngularJS: what is underneath the hood AngularJS: what is underneath the hood
AngularJS: what is underneath the hood DA-14
 

What's hot (20)

AngularJS Routing
AngularJS RoutingAngularJS Routing
AngularJS Routing
 
06 jQuery #burningkeyboards
06 jQuery  #burningkeyboards06 jQuery  #burningkeyboards
06 jQuery #burningkeyboards
 
AngularJS Compile Process
AngularJS Compile ProcessAngularJS Compile Process
AngularJS Compile Process
 
05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards
 
第4回 g* ワークショップ はじめてみよう! Grailsプラグイン
第4回 g* ワークショップ はじめてみよう! Grailsプラグイン第4回 g* ワークショップ はじめてみよう! Grailsプラグイン
第4回 g* ワークショップ はじめてみよう! Grailsプラグイン
 
Cервер на Go для мобильной стратегии
Cервер на Go для мобильной стратегииCервер на Go для мобильной стратегии
Cервер на Go для мобильной стратегии
 
Pengenalan blaast platform sdk
Pengenalan blaast platform sdkPengenalan blaast platform sdk
Pengenalan blaast platform sdk
 
Coding website
Coding websiteCoding website
Coding website
 
The next step, part 2
The next step, part 2The next step, part 2
The next step, part 2
 
jQuery
jQueryjQuery
jQuery
 
Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
jQuery: out with the old, in with the new
jQuery: out with the old, in with the newjQuery: out with the old, in with the new
jQuery: out with the old, in with the new
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performance
 
Performance Optimization In Angular 2
Performance Optimization In Angular 2Performance Optimization In Angular 2
Performance Optimization In Angular 2
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js Fundamentals
 
Understanding Functions and "this" in the World of ES2017+
Understanding Functions and "this" in the World of ES2017+Understanding Functions and "this" in the World of ES2017+
Understanding Functions and "this" in the World of ES2017+
 
AngularJS: what is underneath the hood
AngularJS: what is underneath the hood AngularJS: what is underneath the hood
AngularJS: what is underneath the hood
 
Introducing jQuery
Introducing jQueryIntroducing jQuery
Introducing jQuery
 

Similar to Nodejs do teste de unidade ao de integração

前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说Ting Lv
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Rntb20200805
Rntb20200805Rntb20200805
Rntb20200805t k
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013Laurent_VB
 
Server side data sync for mobile apps with silex
Server side data sync for mobile apps with silexServer side data sync for mobile apps with silex
Server side data sync for mobile apps with silexMichele Orselli
 
TDD in the wild
TDD in the wildTDD in the wild
TDD in the wildBrainhub
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web servicesMichelangelo van Dam
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptRyan Anklam
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015Fernando Daciuk
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejsNick Lee
 

Similar to Nodejs do teste de unidade ao de integração (20)

Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Express JS
Express JSExpress JS
Express JS
 
Rntb20200805
Rntb20200805Rntb20200805
Rntb20200805
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
 
Server side data sync for mobile apps with silex
Server side data sync for mobile apps with silexServer side data sync for mobile apps with silex
Server side data sync for mobile apps with silex
 
TDD in the wild
TDD in the wildTDD in the wild
TDD in the wild
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 
Intro to Ember.JS 2016
Intro to Ember.JS 2016Intro to Ember.JS 2016
Intro to Ember.JS 2016
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 

Recently uploaded

%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durbanmasabamasaba
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...Nitya salvi
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Hararemasabamasaba
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 

Recently uploaded (20)

%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 

Nodejs do teste de unidade ao de integração

  • 1. do teste de unidade ao de integração
  • 2.
  • 3. Teste de unidade → mocha ( $ npm i -D mocha ) → chai ( $ npm i -D chai ) → sinon ( $ npm i -D sinon )
  • 4. $ mkdir -p nodejs-tests/test ; cd nodejs-tests $ npm init -y $ touch index.js test/index.test.js $ npm i -D mocha chai sinon
  • 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); }); }); });
  • 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;
  • 19.
  • 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 Developer at vini.prettodasilva@gmail.com https://github.com/vinicius-pretto/nodejs-automation-tests