> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/contributor/contributor-pt/guias-do-contribuidor/testing-standards/testing-services-deprecated.md).

# Testar Serviços (Deprecated)

{% hint style="warning" %}
Esta é uma abordagem obsoleta para testar serviços. Para novos serviços, por favor consulte [Testing Services (Well-Known-Component)](/contributor/contributor-pt/guias-do-contribuidor/testing-standards/testing-services-wkc.md).
{% endhint %}

Serviços DEVERIAM ser principalmente testados usando **testes de API**, ou seja, um conjunto de testes que exercitam o código do serviço através da sua API iniciando o serviço, com suas dependências externas sendo mockadas (DBs e APIs). **Teste unitário** DEVE ser incluído nos casos em que se encontra trechos utilitários de código com um grande número de casos a serem exercitados ou código não performático, tornando impossível ou difícil testar com testes de API. A justificativa por trás disso é que, devido à nossa arquitetura de micro-serviços, que reduz as responsabilidades e, portanto, a quantidade de código a ser testada, a lógica dos serviços é simples, fazendo dos testes de API a opção com mais valor por tempo ao garantir que os serviços funcionem corretamente.

## Stack de testes

Serviços DEVEM ser testados usando [Jest](https://jestjs.io/) como o framework principal de testes com [supertest](https://github.com/visionmedia/supertest) como o framework para configurar o servidor e testá-lo.

## Estrutura de diretórios

Como os serviços PODEM ter tanto testes de API quanto testes unitários, haverá mais de um lugar onde os testes irão:

* Testes unitários DEVEM ficar ao lado do arquivo ou módulo que estão testando, com o mesmo nome, mas com a extensão `spec.ts` em vez de `ts`.
* Testes de API irão exercitar o código ao longo do serviço, então ELES DEVEM ser colocados em um `diretório de teste` , no caminho raiz. Os arquivos serão nomeados como o recurso do serviço que eles irão testar, ou seja, se os testes de API irão testar o recurso `books`, normalmente sob `/books`, o nome do arquivo DEVE ser `books.spec.ts` e DEVE ser colocado no `diretório de teste` diretório.

## O que testar

* Middlewares aplicados à rota (auth, etc), para garantir que a rota funcione como esperado.
* A lógica dos controllers, para garantir que a rota faça o que esperamos que ela faça.

## Testando serviços via API

Como mencionado antes, testes de API serão feitos usando Jest e supertest.

Para ilustrar como um desenvolvedor fará testes de API, temos o seguinte exemplo:

```tsx
import express from "express"
import { authMiddleware } from "../auth"
import db from "../db"

const app = express()

app.get('/books', async (req, res) => {
	let books: Books[];
	if(req.query.author) {
		books = await db.getFilteredBooks({ author: req.query.author })
	} else {
		books = await db.getBooks()
	}
  res.json(books)
})

app.post('/books', authMiddleware, async (req, res) => {
	await db.insertBook(req.body)
	res.status(200).end()
})
```

Encontramos no exemplo uma rota com diferentes métodos HTTP, GET e POST. Ambos os endpoints referem-se ao mesmo recurso, books, então um arquivo, chamado `books.spec.ts` DEVE ser criado sob o `diretório de teste` diretório para abrigar os testes para eles.

Todas as rotas e os diferentes fluxos de execução DEVEM ser testados minuciosamente. Estes são os casos que o desenvolvedor DEVE testar para esses endpoints:

* Solicitar todos os livros funciona, respondendo com um 200 e a lista de todos os livros.
* Solicitar todos os livros de um determinado autor funciona, respondendo com um 200 e a lista de todos os livros desse autor.
* Publicar um livro sem autenticação falha, respondendo com um 401 e uma mensagem de erro.
* Publicar um livro autenticado funciona, respondendo com um 200 e inserindo o livro.

Esses casos definitivamente terão seus **it**s e a expectativa desses its DEVE conter pelo menos **o status de resposta esperado** e o que é **esperado no corpo da resposta** (se houver).

É assim que esses testes de endpoint devem ser escritos:

```tsx
import db from '../db'
import app from '../express_app.ts'
// Nós apenas mockamos dependências externas como DBs
jest.mock('../db')

const mockDb = db as jest.Mocked<typeof db>

const server = supertest(app.getApp())

// Isto também pode ser escrito como /books?
describe('quando solicitando o recurso books', () => {
	let url: string
	let aBook: Book
	let anotherBook: Book
	beforeEach(() => {
		url = '/books'
		aBook = { title: 'aTitle', author: 'anAuthor' }
		anotherBook = { title: 'anotherTitle', author: 'anotherAuthor' }
	})
	
	describe('quando consultando os books sem um autor', () => {
		beforeEach(() => {
			mockDb.getBooks.mockResolvedValueOnce([aBook, anotherBook])
		})

		it('deve responder com um 200 e todos os livros', () => {
			return server
	      .get(url)
	      .expect(200)
	      .then((response) => {
					expect(response.body).toEqual([aBook, anotherBook])
	      })
		})
	})
	
	describe('quando consultando os books com um autor', () => {
		beforeEach(() => {
			mockDb.getFilteredBooks.mockResolvedValueOnce([anotherBook])
		})

		it('deve responder com um 200 e todos os livros de um autor', () => {
			return server
	      .get(url)
				.query({ author: 'anotherAuthor' })
	      .expect(200)
	      .then((response) => {
					expect(response.body).toEqual([anotherBook])
	      })
		})
	})
	
	describe('quando publicando um novo livro sem autenticação', () => {
		it('deve responder com um 401 e um erro dizendo que o usuário não está autenticado', () => {
			return server
	      .post(url)
				.send(book)
	      .expect(401)
	      .then((response) => {
					expect(response.body).toEqual({ error: 'Unauthenticated' })
	      })
		})
	})
	
	describe('quando publicando um novo livro autenticado', () => {	
		it('deve responder com um 200 e inserir o livro', () => {
			return server
	      .post('/books')
	      .set(createAuthHeaders('post', url))
				.send(aBook)
	      .expect(200)
	      .then(() => {
					// Verifica que o livro foi inserido
	        expect(db.insertBook).toHaveBeenCalledWith(aBook)
	      })
		})
	})
})
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/contributor/contributor-pt/guias-do-contribuidor/testing-standards/testing-services-deprecated.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
