# Probar servicios (obsoleto)

{% hint style="warning" %}
Este es un enfoque en desuso para probar servicios. Para nuevos servicios, por favor consulte [Testing Services (Well-Known-Component)](/contributor/contributor-es/guias-para-colaboradores/testing-standards/testing-services-wkc.md).
{% endhint %}

Los servicios DEBERÍAN probarse principalmente usando **pruebas de API**, es decir, un conjunto de pruebas que ejercitan el código del servicio a través de su API poniendo el servicio en funcionamiento, con sus dependencias externas siendo simuladas (bases de datos y APIs). **Prueba unitaria** DEBERÍA incluirse en los casos donde se encuentren secciones utilitarias de código con un gran número de casos a ejercitar o código no eficiente, lo que hace imposible o difícil probar con pruebas de API. La razón es que, debido a nuestra arquitectura de microservicios, que reduce las responsabilidades y por tanto la cantidad de código a probar, la lógica de los servicios es simple, haciendo que las pruebas de API sean la opción con mejor tiempo por valor al asegurar que los servicios funcionan correctamente.

## Stack de pruebas

Los servicios DEBEN ser probados usando [Jest](https://jestjs.io/) como el framework de pruebas principal con [supertest](https://github.com/visionmedia/supertest) como el framework para levantar el servidor y probarlo.

## Estructura de directorios

Como los servicios PUEDEN tener tanto pruebas de API como pruebas unitarias, habrá más de un lugar donde irán las pruebas:

* Las pruebas unitarias DEBEN ir junto al archivo o módulo que están probando, con el mismo nombre, pero con la extensión `spec.ts` en lugar de `ts`.
* Las pruebas de API ejercitarán el código a lo largo del servicio, por lo que DEBEN colocarse en un `directorio de prueba` , en la ruta raíz. Los archivos serán nombrados como el recurso del servicio que estarán probando, es decir, si las pruebas de API estarán probando el recurso `books`, usualmente bajo `/books`, el nombre del archivo DEBE ser `books.spec.ts` y DEBE colocarse en el `directorio de prueba` directorio.

## Qué probar

* Middlewares aplicados a la ruta (auth, etc.), para asegurar que la ruta funciona como se espera.
* La lógica de los controladores, para asegurar que la ruta hace lo que esperamos que haga.

## Pruebas de API para servicios

Como se mencionó antes, las pruebas de API se harán usando Jest y supertest.

Para ilustrar cómo un desarrollador hará pruebas de API, tenemos el siguiente ejemplo:

```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 en el ejemplo una ruta con diferentes métodos HTTP, GET y POST. Ambos endpoints se refieren al mismo recurso, books, por lo que un archivo, nombrado `books.spec.ts` DEBE ser creado bajo el `directorio de prueba` directorio para contener las pruebas para ellos.

Todas las rutas y los diferentes flujos de ejecución DEBEN ser probados minuciosamente. Estos son los casos que el desarrollador DEBE probar para estos endpoints:

* Solicitar todos los libros funciona, respondiendo con un 200 y la lista de todos los libros.
* Solicitar todos los libros de un autor dado funciona, respondiendo con un 200 y la lista de todos los libros de ese autor.
* Publicar un libro sin autenticación falla, respondiendo con un 401 y un mensaje de error.
* Publicar un libro autenticado funciona, respondiendo con un 200 e insertando el libro.

Estos casos definitivamente obtendrán sus **it**s y la expectativa de esos its DEBE contener al menos **el estado de respuesta esperado** y qué se **espera en el cuerpo de la respuesta** (si lo hay).

Así es como estas pruebas de endpoints deberían escribirse:

```tsx
import db from '../db'
import app from '../express_app.ts'
// Solo simulamos dependencias externas como bases de datos
jest.mock('../db')

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

const server = supertest(app.getApp())

// Esto también podría escribirse como /books?
describe('cuando se solicita el 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('cuando se consultan los books sin un autor', () => {
		beforeEach(() => {
			mockDb.getBooks.mockResolvedValueOnce([aBook, anotherBook])
		})

		it('debería responder con un 200 y todos los books', () => {
			return server
	      .get(url)
	      .expect(200)
	      .then((response) => {
					expect(response.body).toEqual([aBook, anotherBook])
	      })
		})
	})
	
	describe('cuando se consultan los books con un autor', () => {
		beforeEach(() => {
			mockDb.getFilteredBooks.mockResolvedValueOnce([anotherBook])
		})

		it('debería responder con un 200 y todos los books de un autor', () => {
			return server
	      .get(url)
				.query({ author: 'anotherAuthor' })
	      .expect(200)
	      .then((response) => {
					expect(response.body).toEqual([anotherBook])
	      })
		})
	})
	
	describe('cuando se publica un nuevo book sin autenticación', () => {
		it('debería responder con un 401 y un error indicando que el usuario no está autenticado', () => {
			return server
	      .post(url)
				.send(book)
	      .expect(401)
	      .then((response) => {
					expect(response.body).toEqual({ error: 'Unauthenticated' })
	      })
		})
	})
	
	describe('cuando se publica un nuevo book autenticado', () => {	
		it('debería responder con un 200 e insertar el book', () => {
			return server
	      .post('/books')
	      .set(createAuthHeaders('post', url))
				.send(aBook)
	      .expect(200)
	      .then(() => {
					// Comprueba que el book fue insertado
	        expect(db.insertBook).toHaveBeenCalledWith(aBook)
	      })
		})
	})
})
```


---

# Agent Instructions: 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:

```
GET https://docs.decentraland.org/contributor/contributor-es/guias-para-colaboradores/testing-standards/testing-services-deprecated.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
