Estoy probando puntos finales de API y tengo algunas pruebas que son las mismas para cada punto final. En lugar de copiar y pegar, me gustaría compartirlo en una función reutilizable. También quiero que se imprima una declaración en la consola (a través de test ) para cada función, por lo que no quiero combinar la lógica.
Aquí está la función que debe ser compartida:
export function basicTests(res) { test("should respond with a 200 status code", () => { expect(res.statusCode).toBe(200); }); test("should specify json in the content type header", () => { expect(res.headers["content-type"]).toEqual(expect.stringContaining("json")); }); test("should return an ok property", () => { expect(res.body.ok).toBeDefined(); }); test("should return a description property", () => { expect(res.body.description).toBeDefined(); }); }Y así es como llamaría a las pruebas en otro archivo:
let res = {} beforeAll(async () => { const response = await request(app) .get("/some/api/check") .send(); res = { ...response }; }); describe("GET /some/api/route", () => { basicTests(res); // ... more tests }); Actualmente, cuando paso en res , siempre es un objeto vacío. Entonces, incluso si beforeAll se ejecuta antes de las pruebas, la variable parece pasar antes y, por lo tanto, no se actualiza cuando se resuelve Promise .
¿Cómo puedo arreglar esto?
Los casos de prueba se definen de forma síncrona. Eso significa que res es un objeto vacío {} cuando se ejecuta la función basicTests .
beforeAll(fn, timeout) :
Ejecuta una función antes de que se ejecute cualquiera de las pruebas de este archivo. Si la función devuelve una promesa o es un generador, Jest espera a que se resuelva esa promesa antes de ejecutar las pruebas.
Eso significa que la función pasada beforeAll se ejecutará antes de que se ejecuten las funciones de los casos de prueba. Dado que la función devuelve una promesa, jest espera esa promesa.
La principal diferencia es la declaración y el tiempo de ejecución.
Una solución es poner beforeAll things en la función basicTests . P.ej
basicTests.ts :
import request from 'supertest'; export function basicTests(app, route) { describe('basic test suites', () => { let res; beforeAll(async () => { const response = await request(app).get(route); res = { ...response }; }); test('should respond with a 200 status code', () => { expect(res.statusCode).toBe(200); }); test('should specify json in the content type header', () => { expect(res.headers['content-type']).toEqual(expect.stringContaining('json')); }); test('should return an ok property', () => { expect(res.body.ok).toBeDefined(); }); test('should return a description property', () => { expect(res.body.description).toBeDefined(); }); }); } app.ts :
import express from 'express'; const app = express(); app.get('/some/api/check', (req, res) => { res.json({ ok: true, description: null, data: 'a' }); }); export { app }; app.test.ts :
import { basicTests } from './basicTests'; import request from 'supertest'; import { app } from './app'; describe('GET /some/api/route', () => { basicTests(app, '/some/api/check'); let res; beforeAll(async () => { const response = await request(app).get('/some/api/check'); res = { ...response }; }); test('should return data', () => { expect(res.body.data).toBe('a'); }); });resultado de la prueba:
PASS stackoverflow/70702998/app.test.ts (8.972 s) GET /some/api/route ✓ should return data basic test suites ✓ should respond with a 200 status code (2 ms) ✓ should specify json in the content type header ✓ should return an ok property ✓ should return a description property Test Suites: 1 passed, 1 total Tests: 5 passed, 5 total Snapshots: 0 total Time: 9.042 s