unit tests node node.js mongodb unit-testing mocking database

node.js - tests - express js testing



¿Base de datos burlona en node.js? (6)

El propósito de la burla es omitir la complejidad y el código propio de prueba de la unidad. Si quiere escribir pruebas e2e, entonces use db.

Escribir código para configurar / desmontar un DB de prueba para pruebas unitarias es una deuda técnica e increíblemente insatisfactoria.

Hay bibliotecas simuladas en npm:

mongo - https://www.npmjs.com/package/mongomock

mangosta - https://www.npmjs.com/package/mockgoose

Si esos no son compatibles con las características que necesita, entonces sí, es posible que necesite utilizar la función real.

¿Cómo me burlaría de la base de datos en mi aplicación node.js, que en este caso usa mongodb como back-end para una API REST de blog?

Claro, podría establecer la base de datos en una base de datos de testing específica, pero igual podría guardar datos y no probar solo mi código, sino también la base de datos, así que en realidad no estoy haciendo pruebas unitarias sino pruebas de integración.
Entonces, ¿qué debería uno hacer? ¿Crear contenedores de base de datos como una capa intermedia entre la aplicación y db y reemplazar el DAL cuando se está probando?

// app.js var express = require(''express''); app = express(), mongo = require(''mongoskin''), db = mongo.db(''localhost:27017/test?auto_reconnect''); app.get(''/posts/:slug'', function(req, res){ db.collection(''posts'').findOne({slug: req.params.slug}, function (err, post) { res.send(JSON.stringify(post), 200); }); }); app.listen(3000);

// test.js r = require(''requestah'')(3000); describe("Does some testing", function() { it("Fetches a blogpost by slug", function(done) { r.get("/posts/aslug", function(res) { expect(res.statusCode).to.equal(200); expect(JSON.parse(res.body)["title"]).to.not.equal(null); return done(); }); }); ));


Hay una regla general en lo que respecta a la burla que es

No te burles de nada que no te pertenezca.

Si desea simular el archivo db, escóndalo detrás de una capa de servicio abstraída y fingido esa capa. Luego, asegúrese de que la prueba de integración sea la capa de servicio real.

Personalmente, me he alejado de usar simulaciones para probarlas y las uso para el diseño de arriba abajo, ayudándome a impulsar el desarrollo desde la parte superior hacia la inferior burlándose de capas de servicio a medida que avanzo y luego implementando esas capas y escribiendo pruebas de integración. Utilizados como herramienta de prueba, tienden a hacer que su prueba sea muy frágil y en el peor de los casos conduce a una divergencia entre el comportamiento real y el comportamiento burlado.


Mi enfoque preferido para el código DB de pruebas unitarias en cualquier idioma es acceder a Mongo a través de una abstracción de repositorio (hay un ejemplo aquí http://iainjmitchell.com/blog/?p=884 ). Las implementaciones variarán en términos de la funcionalidad específica de DB expuesta, pero al eliminar todo el código de Mongo de su propia lógica, estará en posición de probar la unidad. Simplemente reemplace la implementación de Mongo Repository con una versión apagada que es trivialmente fácil. Por ejemplo, solo almacene objetos en una simple colección de diccionarios en la memoria.

Obtendrá los beneficios de probar su propio código de esta manera sin dependencias de DB, pero igual tendrá que realizar pruebas de integración con el DB principal porque probablemente nunca podrá emular las idiosincrasias de la base de datos real ya que otros tienen dijo aquí. El tipo de cosas que he encontrado son tan simples como la indexación en modo seguro vs sin modo seguro. Específicamente, si tiene un índice único, su implementación de la memoria ficticia podría cumplirlo en todos los casos, pero Mongo no lo hará sin el modo seguro.

Por lo tanto, aunque todavía necesitará probar el DB para algunas operaciones, sin duda podrá probar su propia lógica de manera adecuada con una implementación de Repository aplazada.


No creo que el código relacionado con la base de datos pueda ser probado adecuadamente sin probarlo con el software de la base de datos. Esto se debe a que el código que está probando no es solo javascript sino también la cadena de consulta de la base de datos. Aunque en su caso las consultas parecen simples, no puede confiar en que sea así para siempre.

Por lo tanto, cualquier capa de emulación de base de datos implementará necesariamente toda la base de datos (menos el almacenamiento en disco). Para entonces terminas haciendo pruebas de integración con el emulador de base de datos, aunque lo llames prueba unitaria. Otro inconveniente es que el emulador de base de datos puede terminar teniendo un conjunto diferente de errores en comparación con la base de datos y puede que tengas que codificar tanto el emulador de base de datos como la base de datos (algo así como IE vs Firefox vs Chrome, etc. )

Por lo tanto, en mi opinión, la única forma de probar correctamente su código es relacionarlo con la base de datos real.


No estoy de acuerdo con la respuesta seleccionada u otras respuestas hasta el momento.

¿No sería asombroso si pudieras atrapar los errores generados por los cambios caóticos y muchas veces desordenados realizados en los esquemas DB y tu código ANTES de que llegue al control de calidad? Apuesto a que la mayoría gritaría ¡diablos, sí!

Ciertamente puede y debe aislar y probar sus esquemas DB. Y no lo haces basado en un emulador o imagen pesada o recreación de tu DB y máquina. Esto es qué cosas como SQLite es solo como un ejemplo. Se burla basándose en una instancia liviana de memoria en ejecución y con datos estáticos que no cambian en esa instancia de memoria, lo que significa que realmente está probando su base de datos aisladamente y puede confiar en sus pruebas también. Y, obviamente, es rápido porque está en la memoria, es un esqueleto y se desecha al final de una prueba.

Así que sí debería y debería probar el SCHEMA que se exporta en una instancia de memoria muy liviana de cualquier motor de DB / tiempo de ejecución que esté utilizando, y eso junto con agregar una cantidad muy pequeña de datos estáticos se convierte en su base de datos aislada simulada.

Exporte sus esquemas reales de su base de datos real periódicamente (de forma automatizada) e importelos en su instancia de DB de memoria antes de cada pulsación en el control de calidad, y sabrá instantáneamente si los administradores de base de datos han realizado algún cambio en la base de datos. los desarrolladores que han cambiado el esquema últimamente han roto alguna prueba.

Aunque aplaudo el esfuerzo por hacer todo lo posible para responder, votaría negativamente la respuesta actual si pudiera, pero soy nuevo y aún no he adquirido la reputación suficiente como para habilitar mi habilidad para hacerlo.

En cuanto a la persona que respondió con el mensaje "no se burle de nada que no sea suyo". Creo que quiso decir "no pruebes nada que no te importe". ¡Pero SI te burlas de cosas que no te pertenecen! ¡Porque esas son las cosas que no se prueban y que deben aislarse!

¡Planeo compartir el CÓMO con usted y actualizaré esta publicación en un punto futuro en el tiempo con el código JS de ejemplo real!

Esto es lo que muchos equipos impulsados ​​por pruebas hacen todo el tiempo. Solo tienes que entender cómo.


Tuve este dilema y elegí trabajar con un DB de prueba y limpiarlo cada vez que comienza la prueba. (cómo dejarlo todo: https://.com/a/25639377/378594 )

Con NPM, incluso puede hacer un script de prueba que crea el archivo db y lo limpia después.