2017-08-15 2 views
-5
mocha.js: 3.4.2 
chai.js: 4.1.0 
node.js: 6.10.3 
npm:  5.3.0 

J'ai configuré un harnais de test simple pour un service RESTful déployé sous node.js. Le faisceau de test repose sur mocha.js/chai.js. Chaque test, qui appelle un point de terminaison via https, fonctionne. De même, les fonctions before() et after() sont appelées. CEPENDANT: il semble impossible d'invoquer l'un des points de terminaison RESTful dans la fonction after(). Pourquoi? Comme after() arrive à la fin des tests, je pensais que l'invocation asynchrone de l'extrémité RESTful n'avait tout simplement pas le temps de revenir avant la fin du processus de test. Donc, j'ai codé une boucle d'attente occupée pour donner la réponse un certain temps. No go: l'invocation du point de terminaison ne fonctionne tout simplement pas dans after().mocha/chai.js testing harness: Les appels https ne fonctionnent pas depuis la fonction after()

Voici mon package.json:

{ 
    "name": "so-mcv-example", 
    "version": "1.0.0", 
    "description": "Minimum, Complete, and Verifiable Example", 
    "main": "index.js", 
    "dependencies": { 
     "restify": "^4.3.0" 
    }, 
    "engines": { 
     "node": "6.10.3", 
     "npm": "5.3.0" 
    }, 
    "devDependencies": { 
     "chai": "^4.1.0", 
     "chai-http": "^3.0.0", 
     "mocha": "^3.4.2" 
    }, 
    "scripts": { 
     "test": "mocha" 
    } 
} 

Mon index.js ressemble à ceci:

const restify = require('restify'), 
      fs = require('fs'); 

const server = restify.createServer({ 
    certificate: fs.readFileSync('security/server.crt'), 
    key: fs.readFileSync('security/server.key'), 
    name: 'so-mcv-example' 
}); 

server.listen(443, function() { 
    console.log('%s listening at %s', server.name, server.url); 
}); 

server.pre(restify.pre.userAgentConnection()); 

server.get('/status', function(req, res, next) { 
    res.send({ status: 'so-mcv-example is running ok.' }); 
    return next(); 
}); 

Sous répertoire test, je mocha.opts:

--require ./test/test.bootstrap 

et test.bootstrap.js:

process.env.NODE_ENV = 'test'; 

// CAUTION: never do this in production! For testing purposes, we ignore 
// faults in the standard SSL handshaking. 
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; 

Les paramètres ci négocient le certificat SSL auto-signé employé dans index.js. En test/status-test.js, j'ai:

const chai = require('chai'); 
const expect = chai.expect; 
const should = chai.should(); 
const server = 'https://localhost'; 

chai.use(require('chai-http')); 

before(function() { 
    if (process.env.NODE_ENV != "test") { 
     this.skip(); 
    } 

    // XXX Wipe the database. 
    console.log("Wipe the database BEFORE tests."); 
}); 

describe('GET /status', function() { 
    it('passes, as expected', function(done) { 
     chai.request(server) 
     .get('/status') 
     .end(function(err, res) { 
      expect(err).to.be.null; 
      expect(res).to.have.status(200); 
      done(); 
     }); 
    }); 
}); 

after(function() { 
    if (process.env.NODE_ENV != "test") { 
     this.skip(); 
    } 

    chai.request(server) 
    .get('/status') 
    .end(function(err, res) { 
     expect(err).to.be.null; 
     expect(res).to.have.status(200); 
     console.log("2nd call to /status returned."); 
     done(); 
    }); 
}); 

Il est vrai que, en utilisant chai d'invoquer un point final dans la fonction after() est artificielle. Ce n'est pas le propos. Le fait est que la directive console.log() n'est simplement jamais exécutée. Autrement dit, quand je lance npm test, le résultat est:

> [email protected] test /Users/charlie/workspace/so-mcv-mocha 
> mocha 



Wipe the database BEFORE tests. 
    GET /status 
    ✓ passes, as expected (44ms) 


    1 passing (56ms) 

Voir ma réponse ci-dessous pour une explication sur la raison pour laquelle console.log() n'est pas exécuté.

Pour résoudre le problème, j'ai ajouté une option --no-exit à mocha.opts:

--require ./test/test.bootstrap 
--no-exit 

Puis, quand je lance npm test, le résultat souhaité est sortie:

> [email protected] test /Users/charlie/workspace/so-mcv-mocha 
> mocha 



Wipe the database BEFORE tests. 
    GET /status 
    ✓ passes, as expected (43ms) 


    1 passing (55ms) 

2nd call to /status returned. 
+2

Je pense qu'il serait utile de voir votre code de test. –

Répondre

-1

Je crois avoir trouvé un Solution. Dans after(), si vous appelez de manière asynchrone une extrémité sur un service externe à votre environnement de test, cet appel asynchrone est mis en file d'attente et n'est pas immédiatement exécuté. C'est la nature de l'appel de fonctions asynchrones dans node.js. Eh bien, s'il n'y a pas de logique après l'appel after(), alors mocha se ferme immédiatement en invoquant process.exit()! Le résultat final est que votre appel asynchrone à un point de terminaison externe reste en file d'attente et n'a jamais été appelé.

Résolution: à l'intérieur de mocha.opts sous votre répertoire test, il suffit d'installer l'option --no-exit.

+0

Il pourrait très bien y avoir de meilleures options que d'utiliser '--no-exit' mais nous ne le saurons pas jusqu'à ce que la question soit éditée pour inclure un [mcve]. – Louis

+0

Par votre demande, je suis allé de l'avant et ajouté un exemple à mes notes. Veuillez ajouter des points à ma question. Et si vous fournissez une meilleure réponse, je vais examiner et marquer en conséquence. –