teste-de-integracao.md
0 → 100644
## **TESTES DE INTEGRAÇÃO** | ||
Os testes da aplicação "Adoções" encontram-se no diretório **/api/test**. O modelo abaixo pode ser utilizado para a criação dos testes de integração para os demais recursos da API. | ||
## **Supertest** | ||
Os testes da API utilizam o módulo **supertest** que permite a criação de requisições do tipo: | ||
```javascript | ||
it('GET /usuarios/{id_usuario}', done => { | ||
request | ||
.get(`/usuarios/${nonExistingId}`) | ||
.set("Content-Type", "application/json") | ||
.set("Authorization", "Bearer " + tokenValue) | ||
.end((err, res) => { | ||
expect(res.status).to.equal(404); | ||
done(); | ||
}); | ||
}); | ||
``` | ||
Algumas observações sobre o código acima: | ||
* O parâmetro utilizado para o método **supertest(server)** é uma instância do servidor Restify | ||
* O método .get(`/usuarios/${nonExistingId}`) indica que será feita uma requisição do tipo GET para /usuarios/{id_usuario} | ||
* Os dois métodos set(...) são utilizados para configurar cabeçalhos na requisição (*Content-Type* e *Authorization*, respectivamente) | ||
* No callback do método end estão as asserções. | ||
Sendo assim, o exemplo acima é um GET /usuarios/${nonExistingId} onde a variável nonExistingId é um ID aleatório que não será encontrado. Na asserção expect(res.status).to.equal(404); vemos que o resultado esperado é o status HTTP 404 (Not Found) | ||
## **Definindo os contextos e nomes dos casos de teste** | ||
Uma sugestão é começar defindo os contextos Mocha (com *context*) e os casos de teste (com *it*). No exemplo abaixo, são definidos dois contextos. Em cada contexto os casos de teste são apenas strings indicando os endpoints do recurso Usuario. | ||
```javascript | ||
describe('GET /usuarios/:id_usuario', () => { | ||
context('O usuário informado existe', () => { | ||
it('POST /usuarios'); | ||
it('GET /usuarios'); | ||
it('GET /usuarios/{id_usuario}'); | ||
it('PUT /usuarios/{id_usuario}'); | ||
it('DELETE /usuarios/{id_usuario}'); | ||
it('GET /usuarios/{id_usuario}/perfis'); | ||
it('PUT /usuarios/{id_usuario}/perfis'); | ||
}); | ||
context('O usuário informado não existe', () => { | ||
it('GET /usuarios/{id_usuario}'); | ||
it('PUT /usuarios/{id_usuario}'); | ||
it('DELETE /usuarios/{id_usuario}'); | ||
it('GET /usuarios/{id_usuario}/perfis'); | ||
it('PUT /usuarios/{id_usuario}/perfis'); | ||
}); | ||
}); | ||
``` | ||
## **Preparando o banco de dados** | ||
Abaixo o método **beforeEach** é utilizado para deixar o banco de dados em um estado correto antes de execução de cada caso de teste -- todos os tokens, clientes OAuth e usuarios são removidos e em seguida criados. | ||
```javascript | ||
describe('GET /usuarios/:id_usuario', () => { | ||
const request = supertest(server); | ||
const clienteId = mongoose.Types.ObjectId(); | ||
const tokenValue = "m4m8rF7B8aYsFX2cq0qqg2xzL5jMtxkRu6gSA9sdUGUuganR9rWMQTHGeUSc0rgYaQVom1Z67NW7WXbTkKZfF5W7tBzJ0qsYfmzwrclDjUUtwmcuSBhdkMG1iPPoo4VdryCRxNMhmwRMF2n3aZBWOI1X5kqSoYr0XlgpL7rPMfyDQfZD6g0sN2PvPAq2i6djiwgI72zwQ7yaYEg13esYEXzalhqCTQlIw7MlyiFNI7p8HpZLf8eM1CflQi4APOA8"; | ||
const testUser = { | ||
_id: mongoose.Types.ObjectId(), | ||
email: "[email protected]", | ||
nome: "Usuario Teste", | ||
senha: "123", | ||
perfis: ["administrador"], | ||
ativo: true | ||
} | ||
beforeEach(done => { | ||
Token | ||
.remove({}) | ||
.then(() => Cliente.remove({})) | ||
.then(() => Usuario.remove({})) | ||
.then(() => { | ||
var cliente = new Cliente(); | ||
cliente._id = clienteId; | ||
cliente.nome = "Cliente OAuht 2.0 Para Testes"; | ||
cliente.secret = "$2a$05$M1COhDus0bY6rqkD2REl8.ZccrFgzFXH0a7sOEYU/FWYHTHJ.a8ZC"; | ||
return cliente.save() | ||
}) | ||
.then(() => { | ||
var usuario = new Usuario(testUser); | ||
return usuario.save(); | ||
}) | ||
.then(() => { | ||
var token = new Token(); | ||
token.value = tokenValue; | ||
token.clientId = clienteId; | ||
token.userId = testUser._id; | ||
return token.save(); | ||
}) | ||
.then(() => done()); | ||
}); | ||
context('O usuário informado existe', () => { // casos de teste aqui }); | ||
context('O usuário informado não existe', () => { // casos de teste aqui }); | ||
``` | ||
## **Implementação dos casos de teste** | ||
Por fim, resta implementar os casos de teste. Abaixo, dois exemplos: | ||
```javascript | ||
it('POST /usuarios', done => { | ||
const newUser = { | ||
_id: mongoose.Types.ObjectId(), | ||
email: "[email protected]", | ||
nome: "New User", | ||
senha: "123", | ||
perfis: ["administrador"], | ||
ativo: true | ||
} | ||
request | ||
.post('/usuarios') | ||
.set("Content-Type", "application/json") | ||
.set("Authorization", "Bearer " + tokenValue) | ||
.send(newUser) | ||
.end((err, res) => { | ||
expect(res.status).to.equal(200); | ||
expect(res.body._id).to.equal(newUser._id.toString()); | ||
expect(res.body.email).to.equal(newUser.email); | ||
expect(res.body.nome).to.equal(newUser.nome); | ||
expect(res.body.perfis).to.have.same.members(newUser.perfis); | ||
expect(res.body.ativo).to.equal(newUser.ativo); | ||
// remove usuário criado para neste teste | ||
Usuario | ||
.remove({ _id: newUser._id }) | ||
.then(() => { done() }) | ||
}); | ||
}); | ||
it('GET /usuarios', done => { | ||
request | ||
.get('/usuarios') | ||
.set("Content-Type", "application/json") | ||
.set("Authorization", "Bearer " + tokenValue) | ||
.end((err, res) => { | ||
expect(res.status).to.equal(200); | ||
expect(res.body).to.be.an('array'); | ||
expect(res.body.length).to.equal(1); | ||
done(); | ||
}); | ||
}); | ||
``` | ||
O código completo está no arquivo de testes **/api/test/usuarioIntegration.js** | ||
\ No newline at end of file |