Pruebas de unidad de API de aplicaciones de crud -- javascript campo con unit-testing campo con node.js campo con express.js campo con mocha camp codereview Relacionados El problema

RESTful CRUD application API Unit Tests


2
vote

problema

Español

Así que estoy tratando de aprender TDD / BDD con JavaScript. Estoy creando una aplicación web rellenada simple que usa Get, Publique, Pon y elimine las llamadas API para actualizar los datos en una base de datos de MongoDB y quería ver si había algo que pueda hacer para mejorar la prueba de la unidad que escribí. Ambos para hacerlos más organizados en la salida de prueba, e incluir detalles más específicos que pueden ser importantes desde un punto de vista de prueba.

La aplicación web está construida con la pila media.

  Please enter your desired stop number (or 'quit'): > 3058   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                  Dload  Upload   Total   Spent    Left  Speed 100  7756  100  7679  100    77   4654     46  0:00:01  0:00:01 --:--:--  4656 [[92, 'St-Laurent', ['11:30', '12:00', '12:30']],  [92, 'Stittsville', []],  [96, 'St-Laurent', ['10:51', '11:21', '11:51']],  [96, 'Terry Fox', ['10:09', '10:39', '11:09']],  [118, 'Hurdman', ['11:20', '11:40', '12:00']],  [118, 'Kanata', []],  [162, 'Stittsville', ['11:55', '12:55', '13:55']],  [162, 'Terry Fox', []],  [168, 'Bridlewood', ['11:35', '12:05', '12:35']],  [168, 'Terry Fox', []]] Please enter your desired stop number (or 'quit'): > quit Exiting... 4  
Original en ingles

So I am trying to learn TDD/BDD with Javascript. I am creating a simple RESTful web app that uses GET, POST, PUT, and DELETE API calls to update data in a MongoDB database, and wanted to see if there was anything I can do to improve on the unit test I wrote. Both to make them more organized in the testing output, and to include more specific details that might be important from a testing standpoint.

The web app is built using the MEAN stack.

var superagent = require("superagent"); var chai = require("chai"); var mocha = require("mocha"); var should = require("should"); var expect = chai.expect; var chaiHttp = require('chai-http'); var request = require("request");  var app = require('../app');  var mongoose = require("mongoose"); var campaign = require("../app_api/models/campaigns");     chai.use(chaiHttp);  describe("Campaign API Calls", function() {      var test_id = 0;     var test_campaign_name = "New_Tester_Campaign";      describe("/POST/api/campaigns", function() {         it("should create new campaign with valid input", (done) => {             var campaign = {                 campaignName: test_campaign_name,                 campaignStatus: "active"             }             chai.request(app)                 .post('/api/campaigns')                 .send(campaign)                 .end((err, res) => {                     res.status.should.be.equal(201);                     res.body.should.be.type('object');                     res.body.should.have.property('campaignName').eql(test_campaign_name);                     res.body.should.have.property('campaignStatus');                     res.body.should.have.property('_id');                     test_id = res.body._id;  // Store ID of campaign for use by remaining tests                 done();                 });         });         it("should not create a new campaign with invalid input", (done) => {             var campaign = {                 campaignName: "",                 campaignStatus: "active"             }             chai.request(app)                 .post('/api/campaigns')                 .send(campaign)                 .end((err, res) => {                     res.status.should.be.equal(400);                     res.body.should.have.property('message').eql('Campaign Name is Required');                 done();                 });         });     });      describe("/GET/api/campaigns", function() {         it("it should returns a list of campaigns", (done) => {             chai.request(app)                 .get('/api/campaigns')                 .end((err, res) => {                     res.status.should.be.equal(200);                     res.body.should.be.type('object');                 done();                 });         });     });      describe("/GET/api/campaigns/:campaignid", function () {         it("it should GET the details of one campaign", (done) => {             chai.request(app)                 .get('/api/campaigns/' + test_id)                 .end((err, res) => {                     res.status.should.be.equal(200);                     res.body.should.have.property('campaignName').eql(test_campaign_name);                     res.body.should.have.property('_id').eql(test_id);                 done();                 });         });     });      describe("/PUT/api/campaigns/:campaignid", function () {         it("it should update a single campaign", (done) => {             chai.request(app)                 .put('/api/campaign/' + test_id)                 .field('campaignName', 'Tester_Campaign')                 .end((err, res) => {                     res.status.should.be.equal(200);                     res.body.should.have.property('campaignName')                         .eql('Tester_Campaign');                 don();                 });         });     });      describe("/DELETE/api/campaigns/:campaignid", function() {         it("it should delete a single campaign", function() {             chai.request(app)                 .delete('/api/campaign/' + test_id)                 .end((err, res) => {                     res.status.should.be.equal(200);                     res.body.should.have.property('message')                         .eql('Campaign successfully deleted');                 done();                 });         });     }); }); 
              
     
     

Lista de respuestas

2
 
vote
vote
La mejor respuesta
 

Pruebas de unidad de Api API de aplicaciones de crud

Las pruebas de descanso y unidades ni siquiera deberían pertenecer en la misma oración. Cuando las pruebas de la unidad realizan una solicitud de red, que no es una prueba de unidad .

Si desea Prueba de unidad su API LOGIC , pruebe el código del lado del servidor que comienza desde la parte donde el enrutador se entrega el control a su lógica y más arriba a la capa de ORM. Sus pruebas deben suministrar entradas como si el enrutador los suministrara, y el ORM debería falsarse para suministrar datos como si vinieran de un DB.

      only test this portion           v-----v router <-> logic <-> orm <-> db                     ^---^              you fake this portion  // In the end, you get this: test input  -> logic -> faked orm ----------. test output <-       <- faked db responses <'   

Ahora si lo que realmente quiere decir las pruebas de integración ...

Las pruebas

deben aislarse de los efectos secundarios, particularmente de las pruebas anteriores. De esa manera, las pruebas son independientes en términos de cuando se ejecutan y lo que pasó ante ellos. Si se dejan pasar los efectos secundarios, el estado de la base de datos se vuelve impredecible, las pruebas se vuelven dependientes del orden, lo que los hace quebradizos, una causa de frustración al escribir pruebas. Tan idealmente, antes de cada prueba, restablece su base de datos a un estado conocido.

Por ejemplo, tiene una prueba que POST S una campaña. La siguiente prueba GET SA Campaña que depende de los datos POST PUTANTE. Si, por alguna razón, se deseaba la función POST eliminado, por supuesto que Retire la prueba, que luego rompe la prueba 9988776665544335 . Termina la reescritura de la prueba GET , un esfuerzo innecesario. Si tuviera más pruebas dependiendo de las pruebas anteriores, bueno ... obtienes la idea.

Si está utilizando el nodo 4+, considere usar const en lugar de var , particularmente en sus dependencias. De esa manera, no reemplaza accidentalmente la referencia con otra. Por lo general, ocurre cuando importa el módulo de ruta, y tiene las cosas llamadas path en todo el lugar. Un 99887766655443310 en una asignación a un 99887766655443311 podría significar el desastre para todo el código.

 

RESTful CRUD application API Unit Tests

REST and unit tests shouldn't even belong in the same sentence. When unit tests do a network request, that's not a unit test.

If you want to unit test your API logic, you test the server-side code starting from the part where the router hands off the control to your logic and up to the ORM layer. Your tests should then supply inputs as if the router supplied them, and the ORM should be faked to supply data as if they came from a DB.

    only test this portion           v-----v router <-> logic <-> orm <-> db                     ^---^              you fake this portion  // In the end, you get this: test input  -> logic -> faked orm ----------. test output <-       <- faked db responses <' 

Now if what you really meant integration testing...

Tests should be isolated from side-effects, particularly from previous tests. That way, tests are independent in terms of when they're run and what ran before them. If side-effects are left to happen, the database state becomes unpredictable, tests become dependent on order, making them brittle - a cause of frustration when writing tests. So ideally, before each test, you reset your database to a known state.

For instance, you have a test that POSTs a campaign. The next test GETs a campaign which depends on the data POST put in. If for some reason management wanted the POST feature removed, of course you remove the test - which then breaks the GET test. You end up rewriting the GET test, an unnecessary effort. If you had more tests depending on the previous tests, well... you get the idea.

If you're using Node 4+, consider using const instead of var, particularly in your dependencies. That way, you don't accidentally replace the reference with another. Usually happens when you import the path module, and you have stuff named path all over the place. A missing var on an assignment to a local path could spell disaster for the entire code.

 
 
       
       
1
 
vote
  • POST2 . Será útil porque informará errores como, por ejemplo, la que menciono a continuación. No más días de gasto que persiguen un error causado por llamar a algo POST3 en lugar de POST4 ! (Lo hice una vez. Fue horrible.)
  • POST5 debería ser solo POST6 . Mejor aún, solo diga lo que está asegurándose de que lo haga / tiene, en lugar de POST7 , debe (HEH) ser 99887776655443318
  • No prueba las respuestas, prueba resultados . Si devuelve con éxito a 200 OK y el cuerpo correcto, pero algo se metió cuando realiza la eliminación real, informa el éxito de algo que falló. Debe hacer una segunda prueba para asegurarse de que después de un 200 ok, su contenido se elimine en realidad.
    • Obviamente, la excepción es cuando el resultado es "devolvió una respuesta"
  • CTRL + F POST9 - Usted hizo un error tipográfico. Para citar alguien con más experiencia que yo cuando les pregunté al respecto, " GET0 Se llama después de que se complete una operación de ASYNC. Si no lo llama, la prueba se realizará tiempo después de 2 segundos y fallará. "Probablemente deberías cambiar eso.
  • ¿Por qué tiene tantas líneas en blanco antes de que comience su código? "A lo sumo dos" es una buena regla general para seguir. Más sólo parece innecesario. Sin embargo, realmente no está lastimando nada.
 
  • "use strict";. It'll be useful because it'll report errors like, say, the one I mention down below. No more spending days chasing down a bug caused by calling something foboar instead of foobar! (I did that once. It was awful.)
  • it("it should ...") should probably just be it("should ..."). Better yet, just say what you're making sure it does/has -- instead of it("should GET ..."), it should (heh) be it("returns ... to a GET")
  • Don't test responses, test results. If you successfully return 200 OK and the right body, but something messed up when doing the actual deletion, you're reporting success for something that failed. You need to do a second test to make sure that after a 200 OK, your content is actually deleted.
    • Obviously, the exception is when the result is "returned a response"
  • CTRL+F don() -- you made a typo. To quote someone with more experience than me when I asked them about it, "done is called after an async opertation completes. If you donxe2x80x99t call it, the test will time out after 2 seconds and fail." You should probably change that.
  • Why do you have so many blank lines before your code starts? "At most two" is a good rule of thumb to follow. More just seems unnecessary. It's not really hurting anything, though.
 
 
 
 

Relacionados problema

10  Un makefile para hacer un poco de queso  ( A makefile to make some cheese ) 
Disculpe el juego de palabras en el título, el proyecto se llama " cheddar " (un tipo de queso ). github He estado escribiendo recientemente un idioma...

7  ¿Estoy implementando BDD correctamente?  ( Am i implementing bdd correctly ) 
Estoy escribiendo una utilidad que valida los campos. Decidí probar mi mano en Desarrollo impulsado por el comportamiento (BDD) . El validador utiliza "regla...

15  Prueba modelo de mangosta  ( Test mongoose model ) 
Tengo modelo de mangosta: var mongoose = require('mongoose'), Schema = mongoose.Schema, Imager = require('imager'), env = process.env.NODE_ENV ...

1  Mocha + debería.js, pruebas de nodo  ( Mocha should js testing for node ) 
Soy nuevo en el mundo de la BDD, pero me gustaría obtener un agarre lo antes posible. Es una de mis primeras pruebas: fluido.js 'use strict'; var Fluent...

1  Pruebas Mocha + Chai  ( Mocha chai tests ) 
He estado haciendo un esfuerzo para agregar una buena cantidad de pruebas de unidad en mi código. Sin embargo, me encuentro en contra del principio seco basta...

4  Dirección correcta a la API de la prueba de la unidad  ( Correct way to unit test express api ) 
Escribí una API expresa para un Servicio de Gestión de Documentos (Repo que se encontrará aquí ) Y aunque entiendo la importancia de las pruebas de unidad, n...

1  Pruebas de unidad para una función simple que es parte de una API pública [cerrada]  ( Unit tests for a simple function thats part of a public api ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...

13  Generar una URL, acortarla, insértela en un archivo TEX y compile los archivos TEX  ( Generate a url shorten it insert it in a tex file and compile those tex files ) 
He escrito un módulo NODEJS y sus pruebas para generar una URL, acortarla con BITLY, inserte el enlace corto en un archivo TEX, compile estos archivos TEX a P...

3  Modelo trasero de pruebas de unidad  ( Unit testing backbone model ) 
Me gustaría escuchar la opinión de otras personas sobre cómo la unidad probó una funcionalidad en un modelo de columna vertebral. Como se ve a continuación, e...

3  ¿Estoy usando Q de la manera correcta o hay una mejor manera de hacer lo que estoy haciendo?  ( Am i using q the right way or is there a better way to do what im doing ) 
Estoy usando q para aplanar algunas devoluciones de llamada en mis pruebas de unidad y devolver una promesa a < un href = "http://visionmedia.github.io/moch...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos