Sinon: Documentar cómo configurar Node para permitir el stubbing de módulos EcmaScript

Creado en 8 jun. 2018  ·  17Comentarios  ·  Fuente: sinonjs/sinon

Los módulos EcmaScript que se ejecutan en un entorno que los admite (lo que significa que no se han transpilado usando Babel a ES5) y exportan una función default de algún tipo no se pueden apuntar, ya que los espacios de nombres de ES son inmutables según las especificaciones. Sinon no puede hacer nada al respecto, por lo que arrojamos un error explícitamente cuando intenta hacer esto: 'ES Modules cannot be stubbed' .

Pero @jdalton ha creado esm , un cargador en tiempo de ejecución para Node que permite cargar módulos de EcmaScript ( *.mjs ), y para permitir el stubbing usando Sinon y similares, ha añadido mutableNamespace opción a esm .

Debería haber un artículo en nuestra sección Cómo que muestre cómo se puede configurar npm para ejecutar el nodo usando esm y la opción, junto con un script de prueba.

Referencias:

Documentation ES2015+ Help wanted good first issue hacktoberfest pinned

Comentario más útil

@giltayar ¡ Felicitaciones por implementar el soporte de ESM! Gran artículo, por cierto. Siempre hemos dicho que el stubbing del módulo ES no es posible para conformar los tiempos de ejecución de ESM, pero también hemos dicho (como arriba) que esto debe manejarse en el nivel de enlace, usando algo como proxyquire, rewire o ... Quibble, que es donde agregaste el soporte :)

En mi proyecto de trabajo, hemos usado proxyquire para eliminar las dependencias de los módulos ES:

proxyquire('./mylib.mjs', {doSomething: () => 'done'})

Sería bastante equivalente en Quibble (usado por TestDouble), donde el artículo tiene un ejemplo como este, pero Quibble no admite stubs parciales, así que es un poco diferente en lo que hacen.

await quibble.esm('./mylib.mjs', {doSomething: () => 'done'}, 'yabadabadoing') // not sure what this third param does ...

Entonces, de acuerdo con lo que se ha dicho anteriormente, Sinon nunca agregará explícitamente soporte para burlarse de los módulos ES, ya que es mejor dejarlo en Quibble, Proxyquire, Rewire, NormalModuleReplacementPlugin (paquete web) y todas las otras formas de hacer esto que es 100% entorno dependiente.

Todos 17 comentarios

He estado pensando en escribir exactamente esto :)

El "problema" es que hay una plétora de formas diferentes de usar esm , pero al menos deberíamos cubrir el caso más común, que supongo que es a través de la bandera require hasta la node proceso. Comencé a desarrollar cómo usar el archivo de configuración aquí , pero parece que también es posible proporcionar una cadena json como variable de entorno (además de un hash de opciones si se usa código).

¡Hola @ fatso83!

La opción cjs.mutableNamespace está habilitada de forma predeterminada, por lo que no es necesaria ninguna configuración. El stubbing funcionará con .js pero no con .mjs _ (los archivos .mjs están bloqueados, por lo que no hay opciones de esm ) _.

@jdalton Gracias por js vs mjs . Eso explica por qué este tipo no pudo hacerlo funcionar.

cc @ jim-king-2000

Me gustaría escribir una prueba unitaria con el costo mínimo. Si la solución fuera tan complicada, prefiero abandonar la prueba unitaria con simulacro. Después de todo, la prueba simulada no es el método imperativo para construir un sistema en línea robusto. Pero, como último recurso, ¿es posible que sinon envuelva el "proxyrequire" (o algo así) para mí?

@ jim-king-2000 Eso está fuera de alcance. Ha elegido explícitamente utilizar un sistema de módulos cuyas exportaciones se supone que son inmutables. Desafortunadamente, ese es un costo que tendrá que asumir por su cuenta. Envolver cargadores de módulos, hacer que funcionen en todo tipo de escenarios (nodo, navegador, con / sin transpiladores, etc.) es demasiado costoso y realmente no tiene nada que ver con los objetivos establecidos de este proyecto .

No entiendo muy bien la relevancia de sinon y el sistema de módulos (lo siento). Lo que necesito es un marco de prueba unitario simulado js / node (o biblioteca, como la contraparte de Java, mockito) sin babel. Entonces, ¿existe?

En resumen, para su nicho específico: actualmente no: sollozo:
En general: sí, hay formas de lograr esto para casi cualquier combinación de marcos y tiempos de ejecución.

En términos de Java, es como implementar todo su sistema usando métodos Java static y luego intentar simular las clases usando Mockito. No se puede hacer.

Dicho esto, todo lo que necesita para que las cosas funcionen es cambiar el nombre de sus archivos *.mjs a *.js . Esto parece una vía intermedia pragmática, ya que obtendrá capacidad de prueba sin inconvenientes conocidos.

Para la simulación de la función estática de Java, usamos powermock. Pero puede que no entienda completamente la comparación. Por cierto, no me gusta Java, su evolución es demasiado lenta. Ahora todavía NO es compatible con async / await.

Yo uso * .mjs en todas partes, todos los códigos fuente son archivos mjs. Además, significa que tengo que recurrir a babel nuevamente (introduciendo un trabajo adicional de desarrollo / tiempo de ejecución y una pila de llamadas desordenada). Está bien si solo pudiera volver a cambiar los archivos de prueba a * .js.

Voy a abandonar ut con mock (otras pruebas están intactas) hasta que encuentre otras formas de bajo costo.

@ fatso83 Gracias por la ayuda desde el principio.

¿Alguien trató objeción ? 🤔

Para su información, implementé el soporte ESM de Node.js en "testdouble.js", que es una biblioteca burlona. Es posible. Escribí sobre la implementación en esta publicación de blog:

https://dev.to/giltayar/mock-all-you-want-supporting-es-modules-in-the-testdouble-js-mocking-library-3gh1

Estaría encantado de ayudar aquí si alguien quiere asumirlo ..

@giltayar ¡ Felicitaciones por implementar el soporte de ESM! Gran artículo, por cierto. Siempre hemos dicho que el stubbing del módulo ES no es posible para conformar los tiempos de ejecución de ESM, pero también hemos dicho (como arriba) que esto debe manejarse en el nivel de enlace, usando algo como proxyquire, rewire o ... Quibble, que es donde agregaste el soporte :)

En mi proyecto de trabajo, hemos usado proxyquire para eliminar las dependencias de los módulos ES:

proxyquire('./mylib.mjs', {doSomething: () => 'done'})

Sería bastante equivalente en Quibble (usado por TestDouble), donde el artículo tiene un ejemplo como este, pero Quibble no admite stubs parciales, así que es un poco diferente en lo que hacen.

await quibble.esm('./mylib.mjs', {doSomething: () => 'done'}, 'yabadabadoing') // not sure what this third param does ...

Entonces, de acuerdo con lo que se ha dicho anteriormente, Sinon nunca agregará explícitamente soporte para burlarse de los módulos ES, ya que es mejor dejarlo en Quibble, Proxyquire, Rewire, NormalModuleReplacementPlugin (paquete web) y todas las otras formas de hacer esto que es 100% entorno dependiente.

@ fatso83 Si me

No hay soluciones documentadas en Jest, ninguna está aquí. Casi me rindo hasta que encontré el artículo de @giltayar. Que alivio. Tengo algo que funciona con sutileza hasta que me di cuenta de que puedo usar testdouble.js.

Ya es bastante difícil que en JavaScript cada paquete tenga su propio estilo de documentación y la mayoría de las veces no haya documentos API reales, pero también tener que averiguar cómo funcionan las bibliotecas de prueba, cómo funcionan las bibliotecas simuladas y los cargadores de módulos para las bibliotecas simuladas es demasiado. .

Estoy totalmente de acuerdo si dices que te enfocas en Sinon tal como es mientras que otros pueden enfocarse en conectar esos paquetes juntos para el programador del "usuario final". Solo quiero mostrar que hay un dolor real para los programadores como yo y estoy seguro de que muchos estarían felices si el proceso se simplificara, especialmente si muchos pasarían a los módulos ES en los próximos años.

No tengo un conocimiento técnico tan profundo, solo pensé que algunos comentarios de mi experiencia podrían ser útiles

@ fatso83 Si me

Permítanme reiterar: es la opinión de los mantenedores de Sinon que lidiar con las importaciones simuladas está fuera del alcance de Sinon y es mejor abordado por bibliotecas especializadas.

Generalmente, no tiene sentido hacer una biblioteca que intente hacer todo, en cada tiempo de ejecución. Ni siquiera proyectos de código abierto más grandes y bien financiados intentan hacer esto.

No hay soluciones documentadas en Jest, ninguna está aquí. Casi me rindo hasta que encontré el artículo de @giltayar. Que alivio. Tengo algo que funciona con sutileza hasta que me di cuenta de que puedo usar testdouble.js.

Las diferentes bibliotecas toman diferentes decisiones.

Los mantenedores de testdouble.js toman sus propias decisiones. Decidieron publicar objeciones e integrarlas en su biblioteca. Bien por ellos. Si te gusta su solución, entonces úsala. No tenemos nada más que amor y respeto por @searls y los mantenedores de testdouble.js.

Ya es bastante difícil que en JavaScript cada paquete tenga su propio estilo de documentación y la mayoría de las veces no haya documentos API reales, pero también tener que averiguar cómo funcionan las bibliotecas de prueba, cómo funcionan las bibliotecas simuladas y los cargadores de módulos para las bibliotecas simuladas es demasiado. .

Estoy totalmente de acuerdo si dices que te enfocas en Sinon tal como es mientras que otros pueden enfocarse en conectar esos paquetes juntos para el programador del "usuario final". Solo quiero mostrar que hay un dolor real para los programadores como yo y estoy seguro de que muchos estarían felices si el proceso se simplificara, especialmente si muchos pasarían a los módulos ES en los próximos años.

No estamos aquí para resolver todos los problemas del ecosistema de JavaScript.

Durante más de una década, varios mantenedores han proporcionado la familia de bibliotecas Sinon de forma gratuita. Prácticamente todo el trabajo que se ha dedicado al mantenimiento de estas bibliotecas se ha realizado como trabajo no remunerado, en el tiempo libre de los encargados. Nosotros mismos usamos JavaScript de forma profesional y compartimos sus frustraciones. Pero, solo tenemos un tiempo limitado para regalar.

No tengo un conocimiento técnico tan profundo, solo pensé que algunos comentarios de mi experiencia podrían ser útiles

Lo que sería útil sería si escribiera una publicación de blog sobre sus frustraciones burlándose de las dependencias, hasta que encuentre una solución que funcione bien para usted, y cómo ha utilizado testdouble.js con gran éxito con su forma particular de cargar JavaScript.

Si resulta ser una publicación de blog sólida, me complacerá promocionarla en sinonjs.org .

@mroderick ¡Supongo que primero debería haber

No estamos aquí para resolver todos los problemas del ecosistema de JavaScript.

Definitivamente no, eso solo tenía la intención de mostrar que podría haber una mayor necesidad de ayuda que con otros idiomas (solo mi suposición).

lidiar con las importaciones simuladas está fuera del alcance de Sinon y es mejor abordado por bibliotecas especializadas.

Es bastante justo, como dije, puedo entender eso y probablemente usted tenga una comprensión mucho más profunda del esfuerzo que implica implementar esas características. Además, la API del cargador todavía es experimental.

Actualmente estoy trabajando en una pequeña herramienta CLI que planeo lanzar como código abierto tan pronto como haya una versión funcional. Si eso está hecho, considero escribir una publicación de blog al respecto. Todavía intentaré Sinon con proxyquire antes, porque leí demasiadas cosas buenas sobre Sinon.

Todavía intentaré Sinon con proxyquire antes, porque leí demasiadas cosas buenas sobre Sinon.

Tenemos una guía sobre cómo hacerlo: https://sinonjs.org/how-to/link-seams-commonjs/

Si encuentra que la guía se puede mejorar, envíe una solicitud de extracción 👍

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

ALeschinsky picture ALeschinsky  ·  4Comentarios

brettz9 picture brettz9  ·  3Comentarios

stevenmusumeche picture stevenmusumeche  ·  3Comentarios

ljian3377 picture ljian3377  ·  3Comentarios

NathanHazout picture NathanHazout  ·  3Comentarios