web-dev-qa-db-fra.com

Test des API Mocha: Obtenir 'TypeError: app.address n'est pas une fonction'

Mon problème

J'ai codé une API CRUD très simple et j'ai récemment commencé à coder également des tests utilisant chai et chai-http, mais je rencontre un problème lors de l'exécution de mes tests avec $ mocha.

Lorsque j'exécute les tests, l'erreur suivante s'affiche sur le shell:

TypeError: app.address is not a function

Mon code

Voici un exemple de l'un de mes tests ( /tests/server-test.js ):

var chai = require('chai');
var mongoose = require('mongoose');
var chaiHttp = require('chai-http');
var server = require('../server/app'); // my express app
var should = chai.should();
var testUtils = require('./test-utils');

chai.use(chaiHttp);

describe('API Tests', function() {
  before(function() {
    mongoose.createConnection('mongodb://localhost/bot-test', myOptionsObj);
  });

  beforeEach(function(done) {
    // I do stuff like populating db
  });

  afterEach(function(done) {
    // I do stuff like deleting populated db
  });

  after(function() {
    mongoose.connection.close();
  });

  describe('Boxes', function() {

    it.only('should list ALL boxes on /boxes GET', function(done) {
      chai.request(server)
        .get('/api/boxes')
        .end(function(err, res){
          res.should.have.status(200);
          done();
        });
    });

    // the rest of the tests would continue here...

  });

});

Et mes fichiers d'application express ( /server/app.js ):

var mongoose = require('mongoose');
var express = require('express');
var api = require('./routes/api.js');
var app = express();

mongoose.connect('mongodb://localhost/db-dev', myOptionsObj);

// application configuration
require('./config/express')(app);

// routing set up
app.use('/api', api);

var server = app.listen(3000, function () {
  var Host = server.address().address;
  var port = server.address().port;

  console.log('App listening at http://%s:%s', Host, port);
});

et ( /server/routes/api.js ):

var express = require('express');
var boxController = require('../modules/box/controller');
var thingController = require('../modules/thing/controller');
var router = express.Router();

// API routing
router.get('/boxes', boxController.getAll);
// etc.

module.exports = router;

Notes supplémentaires

J'ai essayé de déconnecter la variable server dans le fichier /tests/server-test.js avant d'exécuter les tests:

...
var server = require('../server/app'); // my express app
...

console.log('server: ', server);
...

et I le résultat est un objet vide: server: {}.

68
charliebrownie

Vous n'exportez rien dans votre module d'application. Essayez d'ajouter ceci à votre fichier app.js:

module.exports = server
153
xersiee

Il est important d'exporter l'objet http.Server renvoyé par app.listen(3000) au lieu de la fonction app sinon vous obtiendrez TypeError: app.address is not a function.

Exemple:

index.js

const koa = require('koa');
const app = new koa();
module.exports = app.listen(3000);

index.spec.js

const request = require('supertest');
const app = require('./index.js');

describe('User Registration', () => {
  const agent = request.agent(app);

  it('should ...', () => {
27
Kim Kern

Cela peut aussi aider et satisfait le point @dman de changer le code de l'application pour l'adapter à un test.

faites votre demande à l'hôte local et portez au besoin chai.request('http://localhost:5000')

au lieu de 

chai.request(server)

cela corrigeait le même message d'erreur que j'avais avec Koa JS (v2) et ava js.

24
Skyguard

Les réponses ci-dessus abordent correctement le problème: supertest veut un http.Server sur lequel travailler. Cependant, appeler app.listen() pour obtenir un serveur démarrera également un serveur d'écoute, ce qui est une mauvaise pratique et n'est pas nécessaire.

Vous pouvez vous déplacer en utilisant http.createServer():

import * as http from 'http';
import * as supertest from 'supertest';
import * as test from 'tape';
import * as Koa from 'koa';

const app = new Koa();

# add some routes here

const apptest = supertest(http.createServer(app.callback()));

test('GET /healthcheck', (t) => {
    apptest.get('/healthcheck')
    .expect(200)
    .expect(res => {
      t.equal(res.text, 'Ok');
    })
    .end(t.end.bind(t));
});

2
Whyhankee

Nous avons eu le même problème lorsque nous exécutons mocha en utilisant ts-node dans notre projet noeudless + TypeScript. 

Notre tsconfig.json avait "sourceMap": true. Les fichiers .js et .js.map ainsi générés entraînent des problèmes de transcription amusants (similaires à ceux-ci). Lorsque nous courons mocha runner en utilisant ts-node. Je vais donc définir le paramètre sourceMap sur false et supprimer tous les fichiers .js et .js.map de notre répertoire src. Ensuite, le problème est parti.

Si vous avez déjà généré des fichiers dans votre dossier src, les commandes ci-dessous seraient très utiles.

find src -name " .js.map" -exec rm {} \; find src -name ". js" -exec rm {} \;

0
Dilunika