Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b02d0df
commit bb562c0
Showing
9 changed files
with
4,388 additions
and
239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# Exercícios práticos sobre teste de software | ||
|
||
Siga as instruções abaixo para instalar as ferramentas utilizadas para melhorar a qualidade da aplicação. | ||
|
||
## 3. Implementando Test Doubles | ||
|
||
### 3.1 Instalando `Sinon`, `sinon-chai` e `Proxyquire` | ||
|
||
A biblioteca [**`Sinon.JS`**](https://sinonjs.org/) é uma biblioteca Javascript para criar test spies, stubs e mocks. Ou seja, simular o comportamento de um módulo para possibilitar a execução de testes unitários. **Sinon** pode ser usada com qualquer framework de testes. | ||
|
||
Vamos utilizar também um módulo chamado `sinon-chai` que, apesar de não ser obrigatório, facilita a leitura e organização dos testes. | ||
|
||
Também devemos prestar atenção às dependências do nosso código. Grande parte das funções depende de bibliotecas externas para executar suas tarefas. Portanto é preciso isolar uma unidade a ser testada que possui uma dependência. Para isso vamos usar o [**`Proxyquire`**](https://www.npmjs.com/package/proxyquire). Para instalar ambas bibliotecas execute: | ||
|
||
```bash | ||
npm install -D sinon sinon-chai proxyquire | ||
``` | ||
|
||
### 3.2 Configurando a aplicação para trabalhar com Stubs | ||
|
||
Vamos usar Stubs anônimos para remover/alterar configurações de ambiente da nossa aplicação, apenas como demonstração. No seu arquivo `package.json` altere a linha 13 (ou a linha que chama o script _test_), para que ela tenha o seguinte conteúdo: `"test": "cross-env DEBUG=restaurant-reservation:* mocha"`. O conteúdo do seu objeto `scripts` deve ficar assim: | ||
|
||
```json | ||
"scripts": { | ||
"debug": "cross-env DEBUG=restaurant-reservation:* nodemon", | ||
"eslint": "eslint", | ||
"test": "cross-env DEBUG=restaurant-reservation:* mocha --recursive", | ||
"start": "node bin/www" | ||
}, | ||
``` | ||
|
||
Podemos também simular como um método responde para validar o comportamento da função que estamos testando e que interage com esse método. Uma vez que sabemos qual a estrutura da resposta de um método, o objetivo é combinar esta estrutura. | ||
|
||
No arquivo `./test/unit/lib/reservations.js`, substituia o seu conteúdo por: | ||
|
||
```javascript | ||
const proxyquire = require('proxyquire'); | ||
const sinon = require('sinon'); | ||
const chai = require('chai'); | ||
const should = chai.should(); | ||
const sinonChai = require('sinon-chai'); | ||
chai.use(sinonChai); | ||
const Reservation = require('../../../lib/schema/reservation'); | ||
const db = require('sqlite'); | ||
|
||
describe('Reservations Library', function() { | ||
const debugStub = function() { | ||
return sinon.stub(); | ||
} | ||
let reservations; | ||
|
||
before(function() { | ||
reservations = proxyquire('../../../lib/reservations', { | ||
debug: debugStub | ||
}); | ||
}); | ||
|
||
context('Validate', function() { | ||
it('should pass a valid reservation with no optional fields', function() { | ||
const reservation = new Reservation({ | ||
date: '2017/06/10', | ||
time: '06:02 AM', | ||
party: 4, | ||
name: 'Family', | ||
email: 'username@example.com' | ||
}); | ||
|
||
return reservations.validate(reservation) | ||
.then(actual => actual.should.deep.equal(reservation)); | ||
}); | ||
|
||
it('should fail an invalid reservation with a bad email', function() { | ||
const reservation = new Reservation({ | ||
date: '2017/06/10', | ||
time: '06:02 AM', | ||
party: 4, | ||
name: 'Family', | ||
email: 'username' | ||
}); | ||
|
||
return reservations.validate(reservation) | ||
.catch(error => error.should.be.an('error').and.not.be.null); | ||
}); | ||
}); | ||
|
||
context('Create', function() { | ||
let dbStub; | ||
let validateSpy; | ||
|
||
before(function() { | ||
dbStub = sinon.stub(db, 'run').resolves({ | ||
stmt: { | ||
lastID: 1349 | ||
} | ||
}); | ||
reservations = proxyquire('../../../lib/reservations', { | ||
debug: debugStub, | ||
sqlite: dbStub | ||
}); | ||
}); | ||
|
||
after(function() { | ||
dbStub.restore(); | ||
}); | ||
|
||
it('should return the created reservation ID', function(done) { | ||
const reservation = new Reservation({ | ||
date: '2017/06/10', | ||
time: '06:02 AM', | ||
party: 4, | ||
name: 'Family', | ||
email: 'username@example.com' | ||
}); | ||
|
||
reservations.create(reservation) | ||
.then(lastID => { | ||
lastID.should.deep.equal(1349); | ||
done(); | ||
}) | ||
.catch(error => done(error)); | ||
}); | ||
}); | ||
}); | ||
``` | ||
|
||
## Próxima seção | ||
|
||
Avançar para exercício [04. Analisando Cobertura de Testes](04.exercicio-cobertura.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.