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 |