Probando una API Node.js

Introducción

Las pruebas son importantes; proporcionan una protección para sus aplicaciones o API. Como principiantes, es posible no tener en cuenta la necesidad de escribir exámenes que cubran las partes importantes de lo que estás construyendo. Sin embargo, se reunirá con él a medida que avance como desarrollador..

En un tutorial anterior, aprendió cómo construir una API con Node.js. Si no lo ha superado, le sugiero que lo haga antes de continuar con esto. En este tutorial, escribirás pruebas para una API creada con Node.js y Express. Al final de este tutorial, sabrá cómo funcionan las pruebas en Node.js, y podrá crear API funcionales y probadas.

Herramientas de prueba

Estarás haciendo uso de Mocha, Expect y Supertest.

Moca es un marco de prueba de JavaScript que hace que las pruebas asíncronas sean simples y divertidas. Mocha viene con toneladas de excelentes características que se pueden encontrar en el sitio web. Estarás haciendo uso de un puñado de ellos..

Esperar es una biblioteca de afirmaciones que le facilita realizar mejores afirmaciones. Verás como funciona eso. Supertesto proporciona una abstracción de alto nivel para probar HTTP. Esto es necesario ya que estarás probando una API.

Basta de hablar, es hora de escribir algo de código.

Configuración del proyecto

Tengo un proyecto de lista de tareas ya configurado para usted. El modelo, el archivo de configuración y parte de app.js ya están listos para usted. Ve a GitHub y clona el repositorio. O simplemente puedes hacer:

git clone https://github.com/izuchukwu1/node-todo-api.git

Tu package.json debería verse así.

# package.json "name": "node-todo-api", "version": "1.0.0", "description": "", "main": "server.js", "scripts": " start ":" node server / server.js "," test ":" export NODE_ENV = test || SET \ "NODE_ENV = test \" && mocha server / ** / *. test.js "," test-watch " : "nodemon --exec 'npm test'", "engines": "node": "8.0.0", "keywords": [], "author": ",, license": "ISC" , "dependencias": "body-parser": "^ 1.17.2", "express": "^ 4.15.3", "lodash": "^ 4.17.4", "mongodb": "^ 2.2.29 "," mongoose ":" ^ 4.11.1 "," devDependencies ": " expect ":" ^ 1.20.2 "," mocha ":" ^ 3.4.2 "," nodemon ":" ^ 1.11.0 "," supertest ":" ^ 3.0.0 "

Ahora ejecuta el comando para instalar las dependencias..

npm instalar

Prueba de solicitud POST

Para su prueba, cree una nueva carpeta llamada prueba; esta carpeta debe estar en tu servidor directorio. Ahora crea un nuevo archivo donde escribirás tu prueba. Nombra el archivo server.test.js.

En este archivo, comience por requerir los módulos que instaló. También necesita requerir su archivo de servidor y su modelo.

# server / test / server.test.js const expect = require ('expect') const request = require ('supertest') const ObjectId = require ('mongodb') const app = require ('./… / server ') const Todo = require (' ./… / models / todo ')

Debe tener algunas tareas pendientes que se utilizarán durante las pruebas. Pero estas tareas pendientes se eliminarán de la base de datos de prueba cada vez que ejecute su conjunto de pruebas. Para manejar eso, crea dos pruebas así.

# server / test / server.test.js const todos = [_id: new ObjectId (), texto: "First test todo", _id: new ObjectId (), texto: "Second test todo", completado: true , completedAt: 333] beforeEach ((done) => Todo.remove (). then (() => return Todo.insertMany (todos)). then (() => done ()) )

El bloque anterior limpia su base de datos de Todo, y luego inserta el conjunto de tareas anteriores. Esto garantiza que tenga una cantidad estable de entradas en su base de datos para que sus pruebas no tengan problemas.

Con eso hecho, puedes escribir la prueba para el ENVIAR solicitud. Para tu ENVIAR Solicitud, va a escribir dos pruebas. El primero hará una solicitud de una tarea válida y tendrá éxito. El segundo hará una solicitud con un cuerpo no válido, y esto no debería crear una nueva tarea pendiente..

Aquí es cómo debe verse la prueba.

# server / test / server.test.js describe ('POST / todos', () => // 1 it ('debe crear una nueva tarea pendiente', (hecho) => let text = 'Prueba la tarea pendiente' // 2 request (app) // 3 .post ('/ todos') .send (text) .expect (200) .expect ((res) => expect (res.body.text) .toBe ( text)) .end ((err, res) => // 4 if (err) return done (err) Todo.find (text). Luego ((todos) => // 5 expect (todos.length) .toBe (1) expect (todos [0] .text) .toBe (text) done ()). catch ((e) => done (e)))) it ('debería no crear todo con datos de cuerpo no válidos ', (hecho) => // 6 request (app) // 7 .post (' / todos ') .send () .expect (400) .end ((err, res) => if (err) return done (err) Todo.find (). then ((todos) => // 8 expect (todos.length) .toBe (2) done ()). captura ((e) => hecho (e)))))

Ejecuta la prueba usando el comando:

npm prueba de carrera

Debería fallar. Esto es lo que está pasando:

  1. Describe la prueba.
  2. Crea una nueva tarea pendiente y la guarda como un valor para el texto..
  3. Usted hace una solicitud POST al / todos ruta de su API, enviando la tarea que ha creado como el cuerpo de la solicitud. Usted espera que el código de estado para la solicitud sea 200 y el cuerpo de la tarea a hacer igual al valor de texto.
  4. Se devuelve un error si hay alguno, y esto hará que la solicitud finalice. Por lo tanto, el siguiente bloque de código no se ejecutará. Si no se encuentra ningún error, el flujo continúa..
  5. Se realiza una solicitud a la base de datos para encontrar la tarea pendiente creada. Usted espera que la longitud de las tareas pendientes en la base de datos sea 1, y que el texto de la tarea pendiente sea igual al valor del texto.
  6. Esta es la prueba hecha con datos corporales inválidos..
  7. UNA ENVIAR solicitud se hace a la / todos camino. Esta vez, estás enviando una solicitud sin cuerpo. Esperas obtener un 400 solicitud. No hay necesidad de revisar el cuerpo ya que no está enviando ninguno. Si se encuentra un error, se devuelve y el código deja de ejecutarse.
  8. Si no se encuentra ningún error, se realiza una solicitud a la base de datos para verificar la longitud de las tareas pendientes. Esperamos que la base de datos contenga solo 2, que son las tareas pendientes creadas al principio.

Para pasar esta prueba, ve a tu server.js Archivar y soltar el código necesario para la solicitud POST.

# server / server.js app.post ('/ todos', (req, res) => let todo = new Todo (text: req.body.text) todo.save (). then ((doc) => res.send (doc), (e) => res.status (400) .send (e)))

Prueba de solicitud GET

Esto es simple: la prueba debe devolver la longitud de las tareas pendientes disponibles en la base de datos. Como ya sabes, la longitud de todos debería ser 2. ¿Por qué? Lo adivinaste. Al comienzo de la suite de pruebas, creó un antes de cada bloque que limpia su base de datos e inserta nuevas tareas pendientes cada vez que se ejecuta el conjunto de pruebas.

Para probar que la solicitud para obtener todas las tareas pendientes, aquí está el código para eso.

# server / test / server.test.js describe ('GET / todos', () => it ('debería obtener todos los', (hecho) => request (app) .get ('/ todos') .expect (200) .expect ((res) => expect (res.body.todos.length) .toBe (2)) .end (done)))

En lo anterior, estás haciendo una OBTENER solicitud a la / todos camino. Esta vez, no está pasando nada como el cuerpo de la solicitud porque es un OBTENER solicitud. Espera obtener una respuesta con el código de estado de 200. Entonces esperas que la longitud de las tareas pendientes sea 2.

Cuando ejecuta la prueba, debe obtener un error. Intenta conseguir el error para pasar por tu cuenta.

Apuesto a que tienes que trabajar. Aquí está el código para obtener la prueba para pasar; compáralo con tu solución.

# server / server.js app.get ('/ todos', (req, res) => Todo.find (). luego ((todos) => res.send (todos), (e) => res.status (400) .send (e)))

Cuando un OBTENER solicitud se hace a la / todos ruta, desea buscar todas las tareas pendientes en la colección Todo y devolverlas como tareas pendientes. Agregando esto a server.js hace que la prueba pase.

A continuación, escribirás tres pruebas para el OBTENER solicitud hecha para recuperar tareas pendientes individuales. El primero debe recuperar y devolver la tarea pendiente. El segundo y el tercero deben volver. 404 error en los casos en que no se encuentra la tarea pendiente.

Abre tu server.test.js y crea un nuevo bloque de descripción con el primer caso de prueba..

# server / server.test.js describe ('GET / todos /: id', () => it ('debería devolver todo doc', (done) => request (app) .get ('/ todos / $ todos [0] ._ id.toHexString () ') .expect (200) .expect ((res) => expect (res.body.todo.text) .toBe (todos [0] .text) ) .end (hecho))

Esta prueba hace una OBTENER solicite recuperar la primera tarea pendiente disponible en su base de datos. Esperas obtener un 200 código de estado, y luego verifique que el valor de texto de la tarea pendiente sea el mismo que el creado.

La siguiente prueba se ve así.

 it ('debería devolver 404 si no se encuentra todo', (done) => let _id = new ObjectId ('5967989ee978311656e93a59') solicitud (app) .get ('/ todos / $ todos / _id.toHexString ()) ') .expect (404) .end (done))

Aquí está buscando una tarea pendiente utilizando una ID que no se corresponde con la ID de ninguna tarea guardada en su base de datos. La prueba espera que esta solicitud devuelva un 404 error.

La última prueba es como la primera pero un poco diferente; aquí es como se ve.

 it ('debería devolver 404 para ids que no son objetos', (hecho) => let hexId = '5967989ee978311656e93a5312' request (app) .get ('/ todos / $ todos / hexId') .expect (404). fin (hecho)))

Aquí, creas un inválido ObjectId y tratar de consultar la base de datos para obtener una tarea pendiente que coincida con la ObjectId creado. La prueba espera que la solicitud devuelva un 404 error. 

Cuando se ejecuta la prueba, todos deben fallar. Para hacer que pasen, agrega el siguiente código a tu server.js expediente.

# server / server.js app.get ('/ todos /: id', (req, res) => let id = req.params.id // 1 if (! ObjectId.isValid (id)) // 2 return res.status (404) .send ('El ID no es válido') Todo.findById (id) .then ((todo) => if (! Todo) // 3 return res.status (404) .send () res.send (todo) // 4). catch ((e) => res.status (400) .send ()))
  1. Obtener el ID de la tarea solicitada de los parámetros.
  2. Compruebe si la identificación es válida. Si el ID no es válido, se envía un error que lo indica..
  3. Si la ID es válida, intente encontrar una tarea pendiente que coincida con esa ID utilizando la findById método. Si no se encuentra ninguna tarea pendiente con ese ID, 404 el error es enviado.
  4. Si se encuentra una tarea pendiente, se envía la tarea pendiente. Entonces atrapas cualquier error que ocurra y lo envías..

Ejecute el comando de prueba una vez más, y debería pasar.

BORRAR Solicitud de prueba

La prueba para tu BORRAR La solicitud será un poco como la que tiene para su solicitud GET.

Primero, quieres probar que una tarea pendiente es eliminada.

# server / test / server.test.js describe ('DELETE / todos /: id', () => it ('debería eliminar un todo', (done) => let hexId = todos [0] ._ id .toHexString () // 1 request (app) .delete ('/ todos / $ hexId') .expect (200) .expect ((res) => expect (res.body.todo._id) .toBe (hexId)) .end ((err, res) => // 2 if (err) return done (err)) Todo.findById (hexId) .then ((todo) => // 3 expect (todo.hexId) .toNotExist () done ()). catch ((e) => done (e)))

Esto es lo que está pasando arriba:

  1. Establece el id de la tarea a una variable llamada hexadec. A continuación, un BORRAR la solicitud se realiza en la ruta de la tarea pendiente, utilizando el ID. Esperas obtener un 200 respuesta, y la tarea pendiente obtenida para que coincida con el valor de hexadec.
  2. Si se encuentra algún error, se devuelve.
  3. Si no hay error, la prueba va más allá para consultar su base de datos utilizando la ID guardada como el valor de hexadec. Desde un BORRAR la solicitud se ha enviado anteriormente, la prueba espera que la tarea pendiente con esa ID no exista.

A continuación, desea probar que cuando se realiza una solicitud para eliminar una tarea pendiente que no existe, la respuesta contiene un 404 error. Es importante tener esto, ya que no es posible eliminar una tarea pendiente dos veces. Aquí es cómo debe verse la prueba para esto.

# server / test / server.test.js it ('debería devolver 404 si no se encuentra todo', (done) => let hexId = new ObjectId (). toHexString () request (app) .delete ('/ todos / $ todos / hexId ') .expect (404) .end (done))

Esto crea una ID para una tarea pendiente que no existe en la base de datos. Entonces un BORRAR Se realiza solicitud para eliminar la tarea pendiente. Se espera que la prueba devuelva un 404 error como la tarea pendiente no existe.

Quieres probar que un BORRAR el uso de una identificación no válida devuelve una 404 error, como asi.

# server / test / server.test.js it ('debería devolver 404 para ids que no son objetos', (hecho) => request (app) .delete ('/ todos / 123abc') .expect (404) .end (hecho) ) )

Para obtener la prueba para pasar, abra su server.js y suelte este.

# server / server.js app.delete ('/ todos /: id', (req, res) => let id = req.params.id if (! ObjectId.isValid (id)) return res.status ( 404) .send () Todo.findByIdAndRemove (id) .then ((todo) => if (! Todo) return res.status (404) .send () res.send (todo)) .catch ((e) => res.status (400) .send ()))

Ejecute el comando para probar:

npm prueba de carrera

Y tus pruebas deberían estar pasando.

Conclusión

En este punto, ahora sabe cómo configurar un conjunto de pruebas al crear una API con Node.js. Ha utilizado Mocha, Expect y Supertest para probar una API. Una de las ventajas de hacer esto es que no es necesario que siempre inicies Postman al crear tu API. Con tu prueba podrás conocer lo que está roto..

Antes de terminar, tenga en cuenta que JavaScript se ha convertido en uno de los idiomas de facto para trabajar en la web. No deja de tener sus curvas de aprendizaje, y también hay muchos marcos y bibliotecas para mantenerte ocupado. Si está buscando recursos adicionales para estudiar o usar en su trabajo, vea lo que tenemos disponible en Envato Market.

Usando lo que ahora sabe, es bueno explorar el mundo de las pruebas.