Creo que investigaré más porque entendí un 50% 🤯🤯
Tu primera experiencia con Node.js
¿Dónde aprender backend con Node.js actualizado?
Todo lo que aprenderás sobre backend con Node.js
¿Qué es Node.js?
¿Qué es Node.js y para qué sirve?
Diferencias entre Node.js y JavaScript
Resumen: Diferencias Nodejs y Javascript
Instalación de Node.js
Arquitectura orientada a eventos
Node.js para la web
Manejo y uso de Streams con Node.js
Introducción a streams
Readable y Writable streams
Duplex y Transforms streams
Uso de utilidades de Node.js
Sistema operativo y sistema de archivos
Administrar directorios y archivos
Consola, utilidades y debugging
Clusters y procesos hijos
Crea tu primer proyecto en Express.js
¿Qué es Express.js y para qué sirve?
Creando tu primer servidor con Express.js
Request y Response Objects
Aprende a crear un API con REST
Anatomía de una API Restful
Estructura de una película con Moockaru
Implementando un CRUD en Express.js
Métodos idempotentes del CRUD
Implementando una capa de servicios
Cómo conectarse con librerías externas en Express.js
Creación de una BD en MongoAtlas
Conexión a MongoAtlas una instancia de MongoDB
Conexión con Robot3T y MongoDB Compass a una BD
Implementación de las acciones de MongoDB
Conexión de nuestros servicios con MongoDB
Conoce como funcionan los Middleware en Express.js
¿Qué es un middleware? Capa de manejo de errores usando un middleware
Manejo de errores asíncronos y síncronos en Express
Capa de validación de datos usando un middleware
¿Qué es Joi y Boom?
Implementando Boom
Implementando Joi
Probar la validación de nuestros endpoints
Middlewares populares en Express.js
Implementa tests en Node.js
Creación de tests para nuestros endpoints
Creación de tests para nuestros servicios
Creación de tests para nuestras utilidades
Agregando un comando para coverage
Debugging e inspect
Despliega tu primera aplicación en Express.js
Considerando las mejores prácticas para el despliegue
Variables de entorno, CORS y HTTPS
¿Cómo implementar una capa de manejo de caché?
¿Cómo contener tu aplicación en Docker?
Despliegue en Now
Conclusiones
¿Qué aprendiste en este curso?
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 43
Preguntas 4
Creo que investigaré más porque entendí un 50% 🤯🤯
¡ESTO ES INCEIBLEMENTE CONFUSO!!!
El profesor va muy muy rápido y no entiendo 😐😥😣
, el cual ya se encuentra modificado con el mock, que le pasamos en el proxyquery.
por lo que el archivo estaría temporalmente modificado para pruebas a esta forma.
Recordemos que MongoLibMock , remplaza el metodo getAll, por lo que regresa un stub de sinon, para simular una respuesta de una consulta al endpoint.
Regresando al test,… este compara getAllStub.called con true, para comprobar si fue llamado.
getAllStub se encuentra en el mock de mongoLib, y es el mismo stub ocupado en el archivo modificado temporalmente de movies.js y en el de pruebas, por eso la función called puede ser utilizada.
Para el segundo test, se compara el mock de pruebas con el que nos regresaría la petición a getMovies({})
Es el mismo archivo, por lo que el test pasa.
Aunque siempre debemos seguir alimentando nuestro conocimiento por nuestra propia cuenta, seria bueno que profundicen mas en ¿el por qué? de las cosas.
Repositorio de la clase:
https://github.com/glrodasz/platzi-backend-node/tree/creacion-de-tests-para-nuestros-servicios
Listo, aunque tengo que repasar.
Los tests siempre han sido mi dolor de cabez :S ¡Necesito profundizar más en test!
Esta lectura esta interesante para entender un poco mas acerca de tests y los terminos nombrados https://solidgeargroup.com/tests-unitarios-en-javascript-sinon/?lang=es
Proxyquire reemplaza los requires originales por los Mock que creamos
He estado horas revisando el codigo pero no puedo hacerlo funcionar, el error que obtengo es TypeError: MoviesService is not a constructor, cuando llamo a const moviesService = new MoviesServices();
alguien me puede ayudar?
Este es mi codigo para services.movies.test.js
const assert = require('assert');
const proxyquire = require('proxyquire');
const { MongoLibMock, getAllStub } = require('../utils/mocks/mongoLib');
const { moviesMock } = require('../utils/mocks/movies');
describe('services - movies', function(){
const MoviesServices = proxyquire('../services/movies', {'../lib/mongo': MongoLibMock});
const moviesService = new MoviesServices();
describe('when getMovies method is called', async function(){
it('should call the getall MongoLib method', async function(){
await moviesService.getMovies({});
assert.strictEqual(getAllStub.called, true);
})
})
})
Y este es mi services/movies.js
`const MongoLib = require(’…/lib/mongo’);
class MoviesService{
constructor() {
this.collection = ‘movies’;
this.mongoDB = new MongoLib();
}
async getMovies({tags}){
const query = tags && { tags: { $in: tags} };
const movies = await this.mongoDB.getAll(this.collection, query);
return movies || [];
}
async getMovie({ movieId }){
const movie = await this.mongoDB.get(this.collection, movieId);
return movie || {};
}
async createMovie({ movie }){
const createdMovieId = await this.mongoDB.create(this.collection, movie);
return createdMovieId;
}
async updateMovie({ movieId, movie}){
const updatedMovieId = await this.mongoDB.update(this.collection, movieId, movie);
return updatedMovieId;
}
async deleteMovie({ movieId }){
const deletedMovieId = await this.mongoDB.delete(this.collection, movieId)
return deletedMovieId;
}
}
module.exports = MoviesService;`
deepEqual() esta deprecado ahora es recomendado deepStrictEqual()
El test falla y no encuentro la razón
routes - movies
GET /movies
√ should respond with status 200 (50ms)
√ should respond with the list of movies
service - movies
when getMovies method is called
√ should call the getAll Mongolib method
1) should return an array of movies
3 passing (214ms)
1 failing
El deepEqual esta obleto
const assert = require('assert');
const proxyquire = require('proxyquire');
const { MongoLibMock, getAllStub} = require('../utils/mocks/mongoLib');
const { moviesMock } = require("../utils/mocks/movies");
describe("service - movies", function(){
const MoviesServices = proxyquire('../services/movies', {
'../lib/mongo': MongoLibMock
});
const moviesService = new MoviesServices();
describe("when getMovies method is called", async function(){
it('should call the getAll Mongolib method', async function(){
await moviesService.getMovies({});
assert.strictEqual(getAllStub.called, true);
});
it('should return an array of movies', async function(){
const result = await moviesService.getMovies({});
const expected = moviesMock;
assert.deepEqual(result, expected, "cual sera el error");
});
});
});
me arroja el siguiente error. Alguna Idea!
ya he comparado mi código con el del profesor y todo esta bien
> backend-con-nodejs@1.0.0 test /Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api
> mocha --exit
ProxyquireError: Invalid stub: "../services/movies" cannot be undefined
at Proxyquire.load (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/proxyquire/lib/proxyquire.js:115:13)
at Suite.<anonymous> (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/test/routes.movies.test.js:8:17)
at Object.create (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/mocha/lib/interfaces/common.js:140:19)
at context.describe.context.context (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/mocha/lib/interfaces/bdd.js:42:27)
at Object.<anonymous> (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/test/routes.movies.test.js:7:1)
at Module._compile (internal/modules/cjs/loader.js:956:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
at Module.load (internal/modules/cjs/loader.js:812:32)
at Function.Module._load (internal/modules/cjs/loader.js:724:14)
at Module.require (internal/modules/cjs/loader.js:849:19)
at require (internal/modules/cjs/helpers.js:74:18)
at requireOrImport (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/mocha/lib/esm-utils.js:15:12)
at Object.exports.loadFilesAsync (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/mocha/lib/esm-utils.js:28:26)
at Mocha.loadFilesAsync (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/mocha/lib/mocha.js:351:19)
at singleRun (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/mocha/lib/cli/run-helpers.js:107:15)
at exports.runMocha (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/mocha/lib/cli/run-helpers.js:144:11)
at Object.exports.handler (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/mocha/lib/cli/run.js:306:11)
at Object.runCommand (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/yargs/lib/command.js:242:26)
at Object.parseArgs [as _parseArgs] (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/yargs/yargs.js:1113:24)
at Object.parse (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/yargs/yargs.js:575:25)
at Object.exports.main (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/mocha/lib/cli/cli.js:68:6)
at Object.<anonymous> (/Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api/node_modules/mocha/bin/mocha:133:29)
at Module._compile (internal/modules/cjs/loader.js:956:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
at Module.load (internal/modules/cjs/loader.js:812:32)
at Function.Module._load (internal/modules/cjs/loader.js:724:14)
at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
at internal/main/run_main_module.js:17:11
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! backend-con-nodejs@1.0.0 test: `mocha --exit`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the backend-con-nodejs@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/carlosramirez/.npm/_logs/2020-04-04T09_39_12_923Z-debug.log
carlosramirez@MacBook-Pro-de-Carlos /Applications/XAMPP/xamppfiles/htdocs/platzi master/backend-con-nodejs/movies-api master
⚡ ```
Me confundí un poco, pero pues seguir con toda y miarar la documentación y explicaciones de los compañeros… 🌸🌞😍
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::.::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Si no estan familiarizados con el describe
o el it
, les recomiendo el curso de testing con jasmine. (exclusivamente en la seccion con Node.js).
Ahí van a poder entender mejor su uso. Tiene una sintaxis muy similar a la de mocha para los tests.
Básicamente el describe
el como un agrupador de las pruebas y el it
es el core del test, en donde se especifica lo que el server debe retornar.
El MongoLibMock reemplaza el uso Mongo, y MoviesServices (con ayuda de proxyquire) simula el comportamiento de la capa de servicio MoviesService
NO HAY QUE RENDIRSE ni desmotivarse si no se comprende todo, es cuestión de investigar un poco.
Pueden entender más sobre “stubs” en este video
✌
Terrible, hay muchas cosas que se pasan por alto y eso que voy con toda la escuela de JavaScript. Empezó muy bien el curso pero estas ultimas clases están muy flojas.
Explicacion del archivo de test creado en esta clase
/** Modulo core que compara variables, valores y objetos de manera estricta */
const assert = require('assert')
/** Modulo de inyeccion de datos / cambia la ruta del require en cualquier modulo */
const proxyquire = require('proxyquire')
/**
* Mock de la libreria de mongo y de sus metodos
* / clase de los metodos de la libreria y detector de peticionees a los metodos
* */
const {
MongoLibMock,
getAllStub
} = require('../utils/mocks/mongoLib')
/** Mock de la DB / lista de peliculas */
const { moviesMock } = require('../utils/mocks/movies')
/**
* Pruebas: toma el archivo de servicios y cambia la ruta de la libreria de mongo
* por la clase exportada de la MongoLibMock. Esto daria como resultado
* una clase con la misma estructura pero que los metodos de la libreria
* de mongo serian mas bien hacia el mock, y se crea una instancia de ella.
*/
describe('services - movies', function() {
const MoviesService = proxyquire('../services/movies.js', {
'../lib/mongo': MongoLibMock
})
const moviesService = new MoviesService()
describe('when getMovies method is called', async function() {
/**
* Prueba hace una peticion al servicio getMovies, como este servicio manda
* a llamar al metodo getAllStub obtenemos una senial mediante sinon
* de que fue llamado el metodo
* getAllStub es el metodo que implantamos mediante proxyquire
* Si efectivamente se llamo, recibiriamos un true del assert, y con esto una prueba exitosa
*/
it('should call the getAll MongoLib method', async function() {
await moviesService.getMovies({})
assert.strictEqual(getAllStub.called, true)
})
/**
* Prueba: que la respuesta obtenida del servicio getMovies sea igual a la que esperamos
* hacemos la peticion y guardamos el resultado, recuerda que se hace al mock de lib
* tomamos el objeto de la lista de datos del mock de movies
* con assert verificamos que sea estrictamente igual
*/
it('should return an array of movies', async function() {
const result = await moviesService.getMovies({})
const expected = moviesMock
assert.deepEqual(result, expected)
})
})
})
Alguien me dice porfa o me termina de definir claramente porque algunos codigos se llaman utilidad? Cuando buenamente puedan y sepan me dicen por favor.
Chicos los tests son súper importantes, no se rindan!!!
Reemplazo Libreria Mongo
Si no usan proxuquire con el metodo load, no va a funcionar esto que hace el profesor. Debe ser nuevo
const MoviesServices = proxyQuire.load('../services/movies', {
'../lib/mongo': MongoLibMock
});
El nuevo test me genera error de timeout, intenté agregando el done() como me sugiere el mensaje de error pero no cambia nada. Mi codigo es el siguiente.
describe('when getMovies method is called', async function () {
it('should call the getAll MongoLib method', async function (done) {
await moviesServices.getMovies({})
assert.strictEqual(getAllStub.called, true)
done()
})
})
sinon
los gigachads como tu y como yo, somos superiores al resto
importamos lo nesesario …
const assert = require('assert');
const proxyquire = require('proxyquire');
const { MongoLibMock, getAllStub } = require('../utils/mocks/mongoLib');
const { moviesMock } = require('../utils/mocks/movies');
reemplazamos la clase que llama a mongoDB por una que llama a los mocks
describe('services - movies', function() {
const MoviesServices = proxyquire('../services/movies', {
'../lib/mongo': MongoLibMock
});
Ahora llamos a nuestro servicio con la nueva clase reemplazada, de forma asincrona, si una lo tiene la de arriba tambien debe
una vez ejecutado el moviesService.getMovies({});
recuerda que este llama en algún momento la función getAllStub
luego preguntamos la función getAllStub. tiene una propiedad llamada called, esta es extrictamente igual a true, es decir getAllStub.called === true
solo que de esta forma el test responde en consola que se cumple o no
describe('when getMovies method is called', async function() {
it('should call the getall MongoLib method', async function() {
await moviesService.getMovies({});
assert.strictEqual(getAllStub.called, true);
});
El siguiente es lo mismo pero esta vez comparará los resulatados
en este caso si guardamos en una variable el resultado y usamos deepEqual ya que compara a varios niveles profundo, queremos esto porque es un objeto
it('should return an array of movies', async function() {
const result = await moviesService.getMovies({});
const expected = moviesMock;
assert.deepEqual(result, expected);
});
});
Una carrera completa de test estaria de lujo!
Para quienes tengan el siguiente error en los test por ESLint
'describe' is not defined.eslint (no-undef)
Se tiene que sumar la siguiente información en el archivo .eslintrc
module.exports = {
env: {
/.../
mocha: true,
},
/.../
};
interesante Mocha para hacer los test
hay que leerse primero la documentation de esos módulos para poder entender mejor
Este curso ha sido el que más me ha costado de la Escuela de Javascript. Creo que explican las cosas muy por encima y da poco contexto de lo que hace.
Sin embargo en cuanto a temas esta muy completo
Los que no entendieron muchas cosas, tomen en cuenta que no es un curso de testing, el testing es TODO un tema, de hecho hay roles en desarrollo de QA que solo se dedican a testear apps, tranquilos, vayan a documentación busquen un curso de testing
potatzio?
Me exploto un poco la cabeza jajaj Esta un poco complejo … pero como todo en programacion (practica) 😄
bastante avanzado y yo con poca experiencia 😕
De a poco se va volviendo mas accesible entenderle a Guillermo, pasa que usa demasiados términos que no explica, o los explica por encima, entiendo que se supone que ya este curso es de nivel “avanzado”, pero es importante que los nombres que salen de lo cotidiano sean explicados, en mi primer clase de programación presencial un muy buen maestro nos dijo: “El esquimal reconoce mas de 7 tipos de blanco en su día a día, gracias a que los puede nombrar”. Vaya bien que me ha hecho esa frase.
😐😥😣
Los tests son un paso fundamental del desarrollo de software, nos ayuda en la mantenibilidad de nuestro código, puesto que cuando alteramos algo o incluimos nuevas caracteristicas, identificamos de forma rápida qué se pudo romper del resto del código.
Cuando trabajamos con esta metodología es importante tener en cuenta para que sirven en describe y el it.
describe Nos ayuda a definir el contexto del test, con el identificamos en primera instancia los test que componen el bloque de pruebas que estamos desarrollando, en este caso sería:
describe('services - movies', function () {
<some code>
});
Luego de identificar el bloque general de las pruebas que vamos a desarrollar, pasamos a configurar el entorno de nuestro test, en esta clase encontramos en esta configuración encontramos el llamado a todos nuestros servicios que queremos probar, y además, estructuramos el entorno en que lo probaremos, en este caso, con el mongo de prueba que configuramos en “mongoLib.js”
Luego de identificar el bloque de pruebas y prearar las configuraciones iniciales, pasamos a crear nuestros test individuales, para identificarlos nos apoyamos de de describe con su función callback que incluirá el test. Cabe destacar que la estructura de un describe es:
describe('Mensaje que identifica nuestro bloque o nuestro test', function() { callback con la lógica del entorno o de los test individuales });
En este caso, cuando desarrollamos test individuales, nos aseguramos de incluir el async en la llamada de la función callback, esto es para realmente esperar la respuesta de nuestro entorno e identificar que están funcionando bien los servicios.
Luego de describir el test individual hacemos un llamado a it, it viene a representar el test que identificamos previamente, en el primer argumento pasaremos el mensaje de nuestro test específico, para identificar que debería ocurrir para que el test sea aprobado, luego, en la función callback que pasamos en el segundo parametro volvemos a llamar al async para esperar nuestra respuesta del test.
Finalmente, dentro del callback de it, vamos a pasar el código que buscamos probar, en este caso es el servicio de getMovies(). Con lo que luego en caso de que el llamado se efectúe correctamente el assert pasará el valor de true validando nuestro test.
Esto resuelve las async que estuvimos configurando previamente y finalmente en consola mocha nos arroja un check por tener el test aprobado.
De esta forma luego en caso de efectuar un cambio a futuro en nuestros servicios podremos evaluarlo en un entorno seguro de forma rápida.
Disculpen lo extenso, aproveché la explicación para también repasar yo 😃
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?