<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Desarrollo y Más]]></title><description><![CDATA[Desarrollo y Más]]></description><link>https://jhymer.dev/</link><image><url>https://jhymer.dev/favicon.png</url><title>Desarrollo y Más</title><link>https://jhymer.dev/</link></image><generator>Ghost 3.6</generator><lastBuildDate>Thu, 08 Jan 2026 13:29:08 GMT</lastBuildDate><atom:link href="https://jhymer.dev/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Optimizar un Entorno de Desarrollo con Docker y Docker-Compose]]></title><description><![CDATA[<p>Docker ha evolucionado a tal punto de ser una herramienta indispensable no solo para el despliegue de aplicaciones sino también, como veremos en este caso, como una herramienta que facilite el desarrollo.</p><h2 id="el-problema">El problema</h2><p>En muchas ocasiones como desarrolladores tenemos que trabajar en múltiples proyectos y en diferentes lenguajes y</p>]]></description><link>https://jhymer.dev/docker-compose-entorno-desarrollo/</link><guid isPermaLink="false">5ecab1fc064b8c03e264ad74</guid><category><![CDATA[docker]]></category><category><![CDATA[javascript]]></category><category><![CDATA[productivity]]></category><dc:creator><![CDATA[Jhymer Martínez]]></dc:creator><pubDate>Sun, 24 May 2020 18:41:38 GMT</pubDate><media:content url="https://jhymer.dev/content/images/2020/05/docker-compose-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://jhymer.dev/content/images/2020/05/docker-compose-1.png" alt="Optimizar un Entorno de Desarrollo con Docker y Docker-Compose"><p>Docker ha evolucionado a tal punto de ser una herramienta indispensable no solo para el despliegue de aplicaciones sino también, como veremos en este caso, como una herramienta que facilite el desarrollo.</p><h2 id="el-problema">El problema</h2><p>En muchas ocasiones como desarrolladores tenemos que trabajar en múltiples proyectos y en diferentes lenguajes y frameworks, a esto se suma una gran cantidad de herramientas y librerías que tenemos que instalar en nuestro sistema ya sea para aprender cosas nuevas o por requerimiento del proyecto. Esto es necesario, y una vez que el proyecto esta funcionado de manera adecuada todo es grandioso, pero que tal si por alguna razón tenemos que cambiar de computador o migrar a otro sistema operativo, el proceso que tenemos que hacer para poner nuevamente nuestro entorno de desarrollo en marcha puede consumir mucho tiempo y esfuerzo.</p><h2 id="-por-qu-utilizar-docker-con-docker-compose">¿Por qué utilizar Docker con Docker Compose?</h2><p>Docker y Docker Compose nos brindan algunos beneficios:</p><ul><li>No necesitamos instalar ni mantener software adicional en nuestro equipo</li><li>Podemos tener todo nuestro entorno de desarrollo en un único repositorio, por ejemplo, tenemos el backend, el frontend y las configuraciones de la base de datos en un mismo repositorio lo que facilita a los desarrolladores el poder colaborar de mejor manera en el proyecto.</li><li>Levantar todo el entorno de desarrollo se limita a un solo comando <code>docker-compose up</code></li></ul><p>Pero no todo es color de rosa, también tenemos una desventaja que está enfocada al rendimiento, ya que a pesar de que los contenedores están enfocados a ser eficientes, siguen consumiendo recursos de la maquina anfitrión tales como procesador y memoria por lo que si la cantidad de contenedores que están corriendo al mismo tiempo es grande o si los contenedores son pesados al momento de crearse y levantarse, podrían llevar a cuelgues del sistema y cosas similares.</p><h2 id="instalaci-n">Instalación</h2><p>Docker Compose depende del motor de Docker (Docker Engine) por lo que antes de empezar a utilizar Docker Compose debemos ya tener instalado Docker en el Sistema.</p><p><strong>En Windows o en Mac:</strong> Docker Compose ya viene incluido dentro del paquete de instalación de Docker Desktop.</p><p><strong>En Linux </strong>primero debemos instalar el motor de Docker y luego seguir unos sencillos pasos descritos en la documentación oficial: <a href="https://docs.docker.com/engine/install/">https://docs.docker.com/engine/install/</a></p><h2 id="ejemplo-pr-ctico">Ejemplo práctico</h2><p>El código de este ejemplo se encuentra disponible en github: <a href="https://github.com/JhymerMartinez/tutorial-docker-compose">https://github.com/JhymerMartinez/tutorial-docker-compose</a></p><p>Vamos a construir una aplicación para gestionar listas de tareas, tanto el backend como el frontend están en carpetas distintas e independientes. Los componentes que conforman este ejemplo son:</p><ul><li><strong>Backend:</strong> Api Rest construida en Express JS encargada de la creación, recuperación y eliminación de tareas.</li><li><strong>Base de Datos:</strong> MongoDB será la base de datos no relacional donde se almacenarán los datos.</li><li><strong>Frontend:</strong> Construido en React JS y es el encargado de presentar de manera visual las tareas mediante el uso de componentes.</li></ul><p><strong>Paso 1. Agregar los Dockerfile</strong></p><p>El Dockerfile es un archivo en texto plano en el cual se especifica una serie de instrucciones a manera de receta para crear una imagen. A una imagen la podemos considerar como una plantilla base para crear el contenedor que contendrá el código de nuestra aplicación.</p><p>En el Backend:</p><pre><code class="language-dockerfile">
# Imagen base de node con una distribución ligera 
# de Linux llamada Alpine
FROM node:12.16.0-alpine

# Directorio que se crea en el contenedor y 
# en donde se ejecutarán otras instrucciones como CMD, 
# COPY o RUN
WORKDIR /app

# Copiar archivo con las dependencias del backend
COPY package.json ./

# Instalar dependencias
RUN npm install

# Copiar todos los demás archivos excepto los 
# ignorados en el archivo .dockerignore
COPY . .

# Puerto que se expone hacia el sistema anfitrión 
EXPOSE 8000

# Valores por defecto para el contenedor 
# en este caso se incluye un ejecutable
CMD ["npm", "start"]</code></pre><p>En el Frontend:</p><pre><code class="language-dockerfile"># Imagen base de node con una distribución ligera 
# de Linux llamada Alpine
FROM node:12.16.0-alpine

# Directorio que se crea en el contenedor y 
# en donde se ejecutarán otras instrucciones como CMD, 
# COPY o RUN
WORKDIR /app

# Copiar archivo con las dependencias del frontend
COPY package.json ./

# Instalar dependencias
RUN yarn install

# Copiar todos los demas archivos excepto los 
# ignorados en el archivo .dockerignore
COPY . .

# Puerto que se expone hacia el sistema anfitrión 
EXPOSE 3000

# Valores por defecto para el contenedor 
# en este caso se incluye un ejecutable
CMD ["yarn", "start"]</code></pre><p><strong>Paso 2. Agregar las variables de entorno</strong></p><p>Docker Compose nos facilita el poder utilizar un archivo independiente con las variables de entorno necesarias para el funcionamiento del proyecto.</p><p>En el backend crearemos un archivo  <code>.env.development</code> en <code>/todo-backend</code> con la siguiente estructura:</p><pre><code class="language-shell-session">NODE_ENV=development
MONGODB_URL=mongodb://mdb:27017/todo-app-db
PORT=8000</code></pre><p>Lo que podemos notar en este archivo es que para realizar la conexión con el contenedor de MongoDB desde el contenedor del Backend utilizamos el nombre del servicio que vamos a especificar en el archivo docker-compose.yml, en este caso es <code>mdb</code>. Esta es la manera en la que se puede realizar la comunicación entre contenedores que han sido especificados como servicios en Docker Compose.</p><p>Ahora en el frontend crearemos un archivo  <code>.env.development</code> en <code>/todo-frontend</code>, aquí simplemente tenemos la ruta en la que estará el API:</p><pre><code class="language-shell-session">REACT_APP_API_URL=http://localhost:8000</code></pre><p><strong>Paso 3. Agregar el archivo docker-compose.yml</strong></p><pre><code class="language-yml">version: '3'
services:
  # Nombre del servicio
  backend:
    # Nombre de la imagen que será generada
    image: todo-backend-image
    # Ruta en donde se encuentra el archivo Dockerfile
    build: ./todo-backend
    # Nombre del contenedor resultante
    container_name: todo-backend
    # Reiniciar el contenedor en caso de ocurrir algún error
    restart: always
    # Ruta al archivo con las variables de entorno
    env_file:
      - ./todo-backend/.env.development
    # Puerto que se expone hacia el sistema anfitrión 
    # desde el contenedor 
    ports:
      - "8000:8000"
    # Directorios del sistema anfitrión que se enlazan 
    # con los del contenedor. El primero es para el
    # código del backend y el segundo para las dependencias
    volumes:
      - ./todo-backend:/app
      - ./todo-backend/node_modules:/app/node_modules
    # Otros servicios de los cuales depende este contenedor 
    depends_on:
      - mdb
    # Red de contenedores a la que se agrega el 
    # contenedor del backend
    networks:
      - todo-network
    # Similar a los especificados en el Dockerfile
    command: sh -c "npm install &amp;&amp; npm start"

  frontend:
    image: todo-frontend-image
    build: ./todo-frontend
    container_name: todo-frontend
    restart: always
    # Mantiene la conexión con el terminal del contenedor
    # en modo interactivo
    stdin_open: true
    env_file:
      - ./todo-frontend/.env.development
    ports:
      - "3000:3000"
    volumes:
      - ./todo-frontend:/app
      - ./todo-frontend/node_modules:/app/node_modules
    networks:
      - todo-network
    command: sh -c "yarn install &amp;&amp; yarn start"

  mdb:
    image: mongo:3.4
    container_name: todo-mongodb
    restart: always
    volumes:
      - ./mongodb/data:/data/db
    ports:
      - "27017:27017"
    networks:
      - todo-network

networks:
  todo-network:</code></pre><p><strong>Paso 4. Levantar el proyecto</strong></p><p>Una vez lista la configuración solo nos resta ejecutar <code>docker-compose up</code> en la raíz del repositorio. Este comando se encargara de construir, iniciar y enlazar los contenedores como servicios. Este proceso puede tomar un poco de tiempo si es la primera vez debido a que tienen que descargarse y construirse las imágenes (si no han sido descargadas previamente) y también descargarse las dependencias del backend y del frontend. Una vez terminado este proceso podemos ir al navegador  y ver el siguiente resultado:</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/05/todo-app.png" class="kg-image" alt="Optimizar un Entorno de Desarrollo con Docker y Docker-Compose"></figure><h2 id="conclusi-n">Conclusión</h2><p>La opción que te he presentado aquí es solo una manera en que podemos utilizar Docker y Docker Compose para facilitarnos el desarrollo, podemos probar con distintos entornos y con diferentes lenguajes, la idea es conseguir optimizar al máximo nuestro entorno de desarrollo y enfocarnos en el principal objetivo que es escribir código de calidad.</p>]]></content:encoded></item><item><title><![CDATA[¿Qué son y para qué sirven los callbacks en JavaScript?]]></title><description><![CDATA[<p>Un callback (llamada de vuelta) en términos comunes es una función que recibe otra función como argumento y la ejecuta en un determinado momento. Para entenderlo mejor usaremos un ejemplo sencillo.</p><p><em><strong>Nota:</strong> Puedes utilizar de la Consola de Desarrollador de Chrome (en MAC: <code>Cmd + Option + J</code> o en Windows: <code>Ctrl</code></em></p>]]></description><link>https://jhymer.dev/que-son-y-para-que-sirven-los-callbacks-en-javascript/</link><guid isPermaLink="false">5e95420d064b8c03e264acbd</guid><category><![CDATA[javascript]]></category><dc:creator><![CDATA[Jhymer Martínez]]></dc:creator><pubDate>Tue, 14 Apr 2020 05:29:28 GMT</pubDate><media:content url="https://jhymer.dev/content/images/2020/04/javascript.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://jhymer.dev/content/images/2020/04/javascript.jpg" alt="¿Qué son y para qué sirven los callbacks en JavaScript?"><p>Un callback (llamada de vuelta) en términos comunes es una función que recibe otra función como argumento y la ejecuta en un determinado momento. Para entenderlo mejor usaremos un ejemplo sencillo.</p><p><em><strong>Nota:</strong> Puedes utilizar de la Consola de Desarrollador de Chrome (en MAC: <code>Cmd + Option + J</code> o en Windows: <code>Ctrl + Shift + J</code>) e ir poniendo a prueba estos ejemplos.</em></p><p>Primero vamos a escribir una función que hará una suma de dos valores y el resultado lo pasará a una función callback que lo presentará en forma de un mensaje de texto en consola:</p><pre><code class="language-javascript">function add(value1, value2, callback) {
    const result = value1 + value2;
    callback(result);
}
</code></pre><pre><code class="language-javascript">function myCallback(result) { 
    console.log(`Result: ${result}`);
}</code></pre><p>Ahora ejecutamos la función <code>add</code>:</p><pre><code class="language-javascript">add(2, 5, myCallback);</code></pre><p>Nos presenta:</p><pre><code class="language-shell-session">Result: 7</code></pre><p>Pero que a ocurrido exactamente. Una de las ventajas que nos brinda JavaScript es la facilidad de poder utilizar funciones en todo momento y como mejor se adapten a nuestras necesidades. En este ejemplo estamos declarando 2 funciones, la primera es <code>add</code> la misma que recibe 3 parámetros un <code>value1</code> que sería el primer número de nuestra suma, un <code>value2</code> que sería el segundo y un <code>callback</code> que a diferencia de los parámetros anteriores no seria un numero sino una función y que a su vez se ejecutará cuando la suma esté completa.</p><p>La segunda función de este ejemplo es <code>myCallback</code> la cual simplemente recibe un valor y lo presenta a manera de mensaje en consola. Lo interesante aquí es que en lugar de llamar a <code>myCallback</code> de manera independiente, la vamos a pasar como un argumento al momento de ejecutar la función suma de la siguiente manera:</p><pre><code class="language-javascript">add(3, 6, myCallback)</code></pre><p>En este ejemplo estamos almacenando el valor de la función callback en una variable llamada <code>myCallback</code> pero también podemos pasarla como una función anónima (sin nombre) directamente a la función <code>add</code> al momento de ejecutarla de la siguiente manera:</p><pre><code class="language-javascript">add(4, 4, function (unResultado) { 
    console.log(`Result: ${unResultado}`);
});</code></pre><p>Obtendremos como resultado:</p><pre><code class="language-shell-session">Result: 8</code></pre><h2 id="-para-qu-sirven-los-callbacks-en-javascript">¿Para qué sirven los callbacks en JavaScript?</h2><p>Los callbacks son muy útiles para manejar la un comportamiento asíncrono en nuestro código. En javascript a diferencia de otros lenguajes, el código no se ejecuta de manera secuencial es decir que el intérprete de javascript no necesariamente tiene que esperar a que finalice una tarea asíncrona (por ejemplo una llamada a una base de datos) antes de avanzar a la siguiente línea de código, es aquí que el uso de callbacks tiene una gran utilidad ya que son funciones que pueden ser ejecutados en cualquier momento.</p><p>Para entender de mejor manera vamos a utilizar un ejemplo valiéndonos de la función <a href="https://www.w3schools.com/jsref/met_win_settimeout.asp ">setTimeout</a> para simular una ejecución asíncrona:</p><pre><code class="language-javascript">function runAsyncTask() {
    console.log(1);
    setTimeout(function() {
  	console.log(2);
    }, 1000);
    console.log(3);
}</code></pre><p>Ahora la ejecutamos:</p><pre><code class="language-javascript">runAsyncTask();</code></pre><p>Obtenemos el siguiente resultado:</p><pre><code class="language-shell-session">1
3
2</code></pre><p>En este ejemplo <code>setTimeout</code> recibe un callback que se ejecutará después de un segundo por esta razón el 2 aparece después del 3.</p><p>Ahora vamos a nombrar a nuestra función callback de la siguiente manera:</p><pre><code class="language-javascript">function myCallback() {
    console.log('This is a callback')
}</code></pre><pre><code class="language-javascript">function runAsyncTask(callback) {
  console.log(1)
  setTimeout(callback, 1000);
  console.log(3)
}</code></pre><p>Ahora ejecutamos la función <code>runAsyncTask</code></p><pre><code class="language-javascript">runAsyncTask(myCallback);</code></pre><p>Y obtenemos el siguiente resultado:</p><pre><code class="language-shell-session">1
3
This is a callback</code></pre><p>Otro uso bastante común de los callbacks es en el manejo de eventos, por ejemplo al momento de hacer clic en un botón deberíamos tener una lógica parecida a la siguiente:</p><pre><code class="language-javascript">document.getElementById("button1").addEventListener("click", function() {
  // do something
});</code></pre><p>En este caso <code>addEventListener</code> recibe 2 parámetros, el primero es el nombre del evento y el segundo es un callback que se ejecutará al momento de que el usuario haga clic sobre el botón con el id  <code>button1</code>.</p><p>Entender cómo funcionan los callback en JavaScript es fundamental a la hora de programar en este lenguaje, además de ser la base para otros conceptos como las promesas y el async/await que posee actualmente JavaScript y que analizaremos más a fondo en un próximo artículo.</p>]]></content:encoded></item><item><title><![CDATA[6 herramientas para trabajar remotamente de manera efectiva]]></title><description><![CDATA[<p>En muchas ocasiones es necesario trabajar remotamente por lo que surge la necesidad de lograr una comunicación efectiva con el equipo y a la vez gestionar adecuadamente nuestros proyectos, para lograr este objetivo podemos recurrir al uso de herramientas digitales que nos faciliten esta tarea.</p><p>A continuación, vamos a analizar</p>]]></description><link>https://jhymer.dev/herramientas-trabajar-desde-casa/</link><guid isPermaLink="false">5e72b5a3064b8c03e264ac5d</guid><category><![CDATA[productivity]]></category><dc:creator><![CDATA[Jhymer Martínez]]></dc:creator><pubDate>Thu, 19 Mar 2020 01:30:28 GMT</pubDate><media:content url="https://jhymer.dev/content/images/2020/03/computer-2982270_1920.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://jhymer.dev/content/images/2020/03/computer-2982270_1920.jpg" alt="6 herramientas para trabajar remotamente de manera efectiva"><p>En muchas ocasiones es necesario trabajar remotamente por lo que surge la necesidad de lograr una comunicación efectiva con el equipo y a la vez gestionar adecuadamente nuestros proyectos, para lograr este objetivo podemos recurrir al uso de herramientas digitales que nos faciliten esta tarea.</p><p>A continuación, vamos a analizar 6 de estas herramientas que considero pueden sernos de utilidad si nuestra meta es una gestión efectiva</p><h2 id="slack">Slack</h2><p>Es una herramienta de mensajería en tiempo real que facilita la comunicación del equipo de trabajo. Permite la creación de grupos, conversaciones privadas, canales públicos y privados, compartir archivos y muchas otras opciones, a mas de esto posee una gran cantidad de configuraciones adicionales que van desde cambiar como y cuando se presentan las notificaciones hasta cambios en los colores del tema.</p><p>Posee una versión web, versión móvil para ios y Android, y una versión de escritorio para Windows, Linux y Mac Os</p><p>Otro fuerte de Slack es la cantidad de integraciones con las que cuenta, entre las que destacan Google Drive, Google Hangouts, Dropbox, Skype y muchos otros más.</p><p>Posee varios planes de pago, pero también una versión gratuita que resulta más que suficiente para pequeñas empresas o autónomos.</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/03/Screen-Shot-2020-03-18-at-7.26.05-PM.png" class="kg-image" alt="6 herramientas para trabajar remotamente de manera efectiva"></figure><p>Pagina web de Slack: <a href="https://slack.com">https://slack.com</a></p><h2 id="google-hangouts">Google Hangouts</h2><p>Es un sistema especializado en comunicación ya sea mediante audio, video o ambos. Es desarrollado por Google y esta enfocado en la realización de videoconferencias de una manera sencilla y eficaz.</p><p>Esta disponible desde un ordenador o desde una aplicación móvil ya sea en Android o ios tanto en celulares como en tablets.</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/03/Screen-Shot-2020-03-18-at-7.19.04-PM.png" class="kg-image" alt="6 herramientas para trabajar remotamente de manera efectiva"></figure><p>Página web de Google Hangouts: <a href="https://hangouts.google.com">https://hangouts.google.com</a></p><h2 id="zoom">Zoom</h2><p>Es una herramienta enfocada en videoconferencias, posee planes gratuitos y de pago y permite hacer conferencias con una gran cantidad de personas conectadas al mismo tiempo con audio y video en directo. Zoom da la posibilidad de crear diferentes salas y subsalas virtuales para facilitar el trabajo en equipo.</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/03/Screen-Shot-2020-03-18-at-7.29.39-PM.png" class="kg-image" alt="6 herramientas para trabajar remotamente de manera efectiva"></figure><p>Página web de Zoom: <a href="https://zoom.us/">https://zoom.us</a></p><h2 id="google-calendar">Google Calendar</h2><p>Es un servicio de calendario gratuito de google, permite organizar eventos y compartirlos entre tus contactos de google. Otras características son el uso compartido del calendario, búsqueda avanzada de eventos ya sea en tu calendario o en calendarios públicos, soporte móvil tanto para Android como ios y notificaciones para que no pierdas ningún evento que hayas planificado con anterioridad.</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/03/Screen-Shot-2020-03-18-at-7.13.12-PM.png" class="kg-image" alt="6 herramientas para trabajar remotamente de manera efectiva"></figure><p>Página web de Google Calendar: <a href="https://www.google.com/calendar">https://www.google.com/calendar</a></p><h2 id="microsoft-todo">Microsoft todo</h2><p>Esta herramienta permite la gestión y sincronización de listas de tareas entre distintos dispositivos. Al pertenecer a Microsoft posee integración con Office 360 y correo Outlook.</p><p>Esta disponible gratis para Windows, Mac OS, iOS, Android y en versión online para el navegador web.</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/03/Screen-Shot-2020-03-18-at-7.28.23-PM.png" class="kg-image" alt="6 herramientas para trabajar remotamente de manera efectiva"></figure><p>Página web de To Do: <a href="https://todo.microsoft.com">https://todo.microsoft.com</a></p><h2 id="trello">Trello</h2><p>Esta fabulosa herramienta permite la organización de tareas de una manera sencilla. Esta enfocada en la coordinación de equipos de trabajo remoto y se basa en la metodología Kanban la cual busca gestionar de manera generalizada cómo se van completando las tareas.</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/03/Screen-Shot-2020-03-18-at-7.17.00-PM.png" class="kg-image" alt="6 herramientas para trabajar remotamente de manera efectiva"></figure><p>Página web de Trello: <a href="https://trello.com/">https://trello.com/</a></p>]]></content:encoded></item><item><title><![CDATA[Integrar Jest con Enzyme en un proyecto React (Create React App)]]></title><description><![CDATA[<p>Este artículo esta basado en <a href="https://blog.usejournal.com/testing-with-jest-and-enzyme-in-react-part-1-162ce7466128">https://blog.usejournal.com/testing-with-jest-and-enzyme-in-react-part-1-162ce7466128</a></p><p><a href="https://reactjs.org/">ReactJS</a> es una librería Javascript diseñada para la creación de Interfaces web, es mantenida por Facebook y ampliamente utilizada en la actualidad.</p><h2 id="jest">Jest</h2><p><a href="https://jestjs.io/">Jest</a> es un framework creado para realizar Pruebas Unitarias (Unit Testing) enfocado en la simplicidad y la</p>]]></description><link>https://jhymer.dev/integrar-jest-con-enzyme-en-un-proyecto-react-create-react-app/</link><guid isPermaLink="false">5e575016064b8c03e264aae8</guid><category><![CDATA[react]]></category><category><![CDATA[jest]]></category><category><![CDATA[enzyme]]></category><category><![CDATA[unit testing]]></category><dc:creator><![CDATA[Jhymer Martínez]]></dc:creator><pubDate>Thu, 27 Feb 2020 06:00:55 GMT</pubDate><media:content url="https://jhymer.dev/content/images/2020/02/Screen-Shot-2020-02-26-at-3.28.57-PM-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://jhymer.dev/content/images/2020/02/Screen-Shot-2020-02-26-at-3.28.57-PM-1.png" alt="Integrar Jest con Enzyme en un proyecto React (Create React App)"><p>Este artículo esta basado en <a href="https://blog.usejournal.com/testing-with-jest-and-enzyme-in-react-part-1-162ce7466128">https://blog.usejournal.com/testing-with-jest-and-enzyme-in-react-part-1-162ce7466128</a></p><p><a href="https://reactjs.org/">ReactJS</a> es una librería Javascript diseñada para la creación de Interfaces web, es mantenida por Facebook y ampliamente utilizada en la actualidad.</p><h2 id="jest">Jest</h2><p><a href="https://jestjs.io/">Jest</a> es un framework creado para realizar Pruebas Unitarias (Unit Testing) enfocado en la simplicidad y la velocidad. Algunas de sus características principales son:</p><p>•	Permite la ejecución de pruebas en paralelo para maximizar el rendimiento.<br>•	Es una librería de aserciones (assertion library).<br>•	Permite la construcción de mocks de manera similar a Sinon JS.<br>•	Ofrece la posibilidad de crear informes de cobertura.<br>•	Fácil de configurar.</p><h2 id="enzyme">Enzyme</h2><p><a href="https://airbnb.io/enzyme">Enzyme</a> es una utilidad diseñada para React JS con el fin de facilitar la creación de pruebas para los Componentes hechos en React</p><h2 id="comenzando-con-jest">Comenzando con Jest</h2><p></p><ol><li><strong>Crear una aplicación utilizando create-react-app</strong></li></ol><p>Antes de empezar con a integrar Jest en nuestro proyecto primero debemos crearlo, para esto usaremos la herramienta <a href="https://reactjs.org/docs/create-a-new-react-app.html">create-react-app</a> </p><pre><code class="language-shell-session">npx create-react-app react-jest-app
cd react-jest-app
npm start </code></pre><p><strong>Nota:</strong> npx es una utilidad creada para ejecutar paquetes localmente o en este caso ejecutar paquetes sin necesidad de instalarlos globalmente.</p><p>La estructura del proyecto debe lucir como se muestra a continuación:</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/02/Screen-Shot-2020-02-26-at-9.15.26-PM.png" class="kg-image" alt="Integrar Jest con Enzyme en un proyecto React (Create React App)"></figure><p><strong>2. Ejecutando una prueba de demostración con Jest</strong></p><p>•	Primero debemos borrar el archivo <strong>App.test.js</strong> que viene por defecto.<br>•	Instalamos Jest como dependencia de desarrollo.</p><pre><code class="language-shell-session">npm install --save-dev jest</code></pre><p>•	Modificamos en nuestro <strong>package.json</strong> el script test con el valor <strong>jest.</strong></p><pre><code class="language-json">{
  "name": "react-jest-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "react-scripts": "3.4.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      "&gt;0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
  "devDependencies": {
    "jest": "^25.1.0"
  }
}</code></pre><p>•	Creamos una carpeta <strong>test</strong> en la raíz del proyecto.<br>•	Dentro de <strong>/test</strong> agregamos un nuevo archivo <strong>demo.test.js</strong> con el siguiente contenido:</p><pre><code class="language-javascript">it("suma correctamente", () =&gt; {
  expect(1+1).toEqual(2);
});</code></pre><p>•	Nuestro proyecto debe lucir de la siguiente manera:</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/02/Screen-Shot-2020-02-26-at-9.32.06-PM.png" class="kg-image" alt="Integrar Jest con Enzyme en un proyecto React (Create React App)"></figure><p>•	Abrimos un terminal y ejecutamos el siguiente comando</p><pre><code class="language-shell-session">npm test</code></pre><p>•	Deberíamos ver el siguiente resultado</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/02/Screen-Shot-2020-02-26-at-9.33.36-PM.png" class="kg-image" alt="Integrar Jest con Enzyme en un proyecto React (Create React App)"></figure><p><strong>Explicación</strong></p><p>•	Cuando ejecutamos el comando <strong>npm test</strong> automáticamente se ejecuta Jest con las configuraciones por defecto.<br>•	Por defecto Jest busca todos los archivos que con extensión <strong>.test.js</strong> y los identifica como archivos con pruebas unitarias.<br>•	En la prueba estamos esperando que las suma de 1 + 1 sea igual a 2.</p><p><strong>3. Instalando Enzyme</strong></p><p>•	Instalamos la librería Enzyme y el adaptador acorde a nuestra versión de React, en mi caso estamos usando react 16.13 por lo que necesitamos enzyme-adapter-react-16</p><pre><code class="language-shell-session">npm install --save-dev enzyme enzyme-adapter-react-16</code></pre><p><strong>4. Instalando babel-preset-env</strong></p><p>•	<a href="https://babeljs.io/docs/en/babel-preset-env">babel-preset-env</a> permite utilizar las nuevas características de ES6 en nuestras pruebas.</p><p>Ahora nuestro <strong>package.json</strong> se ve así:</p><pre><code class="language-json">{
  "name": "react-jest-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "react-scripts": "3.4.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      "&gt;0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "babel-preset-env": "^1.7.0",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "jest": "^25.1.0"
  }
}</code></pre><p><strong>5. Configuración de Babel</strong></p><p>Vamos a crear un archivo <strong>.babelrc</strong> en la raíz del proyecto con el siguiente contenido:</p><pre><code class="language-json">{
  "presets": [
    "@babel/preset-env",
    "react-app"
  ]
}</code></pre><p><strong>Nota:</strong> Los presets <strong>react-app</strong> ya vienen incluidos al momento de crear el proyecto con <strong>create-react-app</strong> por lo que no es necesario instalarlos de nuevo (<a href="https://www.npmjs.com/package/babel-preset-react-app#usage-in-create-react-app-projects">https://www.npmjs.com/package/babel-preset-react-app#usage-in-create-react-app-projects</a>)</p><p><strong>6. Configuración para Jest</strong></p><p>•	Dentro de la carpeta <strong>/test</strong> vamos a crear un archivo <strong>setupTests.js</strong> con el siguiente contenido:</p><pre><code class="language-javascript">import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';;

// React 16 Enzyme adapter
Enzyme.configure({ adapter: new Adapter() });</code></pre><p>•	Agregamos una configuración adicional en nuestro <strong>package.json</strong> apuntando al archivo de configuración</p><pre><code class="language-json">...
  "jest": {
    "setupFilesAfterEnv": [
      "./test/setupTests.js"
    ]
  }
...</code></pre><p>•	Ahora nuestro <strong>package.json</strong> se ve así</p><pre><code class="language-json">{
  "name": "react-jest-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "react-scripts": "3.4.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      "&gt;0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "babel-preset-env": "^1.7.0",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "jest": "^25.1.0"
  },
  "jest": {
    "setupFilesAfterEnv": [
      "./test/setupTests.js"
    ]
  }
}</code></pre><p><strong>7. Crear un componente de prueba</strong></p><p>•	Dentro de la carpeta <strong>/src</strong> vamos a crear una nueva carpeta llamada components.<br>•	Dentro de <strong>/src/components</strong> crearemos una carpeta <strong>Title</strong> y dentro de esta un <strong>index.js</strong> con el siguiente contenido:</p><pre><code class="language-javascript">import React from 'react';

const Title = ({ children }) =&gt; (
  &lt;h1&gt;{children}&lt;/h1&gt;
);

export default Title;</code></pre><p><strong>8. Escribir una prueba con Jest y Enzyme</strong></p><p>•	Dentro de la carpeta <strong>/test</strong> vamos a crear un nuevo archivo <strong>Title.test.js</strong> con el siguiente contenido:</p><pre><code class="language-javascript">import React from 'react';
import { shallow } from 'enzyme';
import Title from '../src/components/Title';
const title = 'Test Title';
let wrapped = shallow(
  &lt;Title&gt;{title}&lt;/Title&gt;
);
describe('Title', () =&gt; {
  it('renders the Titles children', () =&gt; {
    expect(wrapped.find('h1').text()).toEqual(title);
  });
});</code></pre><p>•	En esta prueba estamos validando que el texto que se presenta dentro de la etiqueta <code>&lt;h1&gt;</code> del componente Test coincida con el contenido que esta siendo agregado como hijo al momento de utilizar el componente.</p><p>Ahora la estructura de nuestro proyecto luce así:</p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/02/Screen-Shot-2020-02-27-at-12.04.23-AM.png" class="kg-image" alt="Integrar Jest con Enzyme en un proyecto React (Create React App)"></figure><p>•	En un terminal solo nos queda ejecutar <strong>npm test</strong></p><figure class="kg-card kg-image-card"><img src="https://jhymer.dev/content/images/2020/02/Screen-Shot-2020-02-27-at-12.05.41-AM.png" class="kg-image" alt="Integrar Jest con Enzyme en un proyecto React (Create React App)"></figure><p>Código en Github: <a href="https://github.com/JhymerMartinez/react-jest-app">https://github.com/JhymerMartinez/react-jest-app</a></p>]]></content:encoded></item></channel></rss>