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 |