Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use supertest with hapi?

I'm using hapi, not express. Should supertest still work?

If so, is there a quick way to change my code to get it to run?

My test looks like this, based on the documentation:

import tape = require('tape');
const supertest = require('supertest');
const app = require('../../../../src/app');

tape('creates new user in database', function (assert) {
  supertest(app)
    .get('/ekapi/v1/signup')
    .expect(200)
    ......
});

but it gives me this error:

dist/server/app/node_modules/supertest/lib/test.js:55
  var addr = app.address();
                 ^

TypeError: app.address is not a function
    at Test.serverAddress (/home/rje/projects/ekaya/dist/server/app/node_modules/supertest/lib/test.js:55:18)

Here's my app code:

app.ts

import './core/externalTypes/imports';
import 'reflect-metadata';
import kernel from './core/inversify.config';
import {IServer}  from './core/types/IServer';

let server = kernel.get<IServer>("IServer");
server.start();

server.ts

import _ = require('lodash');
import * as hapi from "hapi";
import { injectable, inject } from "inversify";
import { IServer } from "../core/types/IServer";
import { ISignUpRoute } from "../core/types/ISignUpRoute";
import { IRouteHandler } from "../core/types/IRouteHandler";
import { IDatabase } from "../core/types/IDatabase";
import { IConfig } from "../core/types/IConfig";
import { IValidator } from "../core/types/IValidator";

@injectable()
class Server implements IServer
{
    _db : IDatabase;
    _server: hapi.Server;
    _config: IConfig;
    _validator: IValidator;
    _routes: [IRouteHandler];

   constructor(
        @inject("IDatabase") db: IDatabase,
        @inject("IConfig") config: IConfig,
        @inject("IValidator") validator: IValidator,
        @inject("ISignUpRoute") signUpRoute: ISignUpRoute)
    {
        this._db = db;
        this._config = config;
        this._validator = validator;
        this._routes = [signUpRoute];
      this._server = new hapi.Server();
      this._server.connection({
          host: '0.0.0.0',
          port: this._config.webservice_port,
             routes: { cors: true }
      });
        this.addRoutes();
   }

    start() : void
    {
        this._server.start((err : any) => {
             if (err)
                  throw err;
             console.log('Hapi server running at: ', this._server.info.uri);
        });
    }

    addRoutes() : void {
        const self = this;
        this._routes.map(function(routeHandler : IRouteHandler) {
            self._server.route(routeHandler.getRoute());
        });
    }

}

export = Server;
like image 510
Richard Avatar asked May 25 '16 14:05

Richard


People also ask

What is glue in Hapi JS?

Glue provides configuration based composition of hapi's Server object. Specifically it wraps. server = Hapi.server(Options) server.register(Plugins, Options)

What is SuperTest in JS?

SuperTest is a Node. js library that helps developers test APIs. It extends another library called superagent, a JavaScript HTTP client for Node. js and the browser. Developers can use SuperTest as a standalone library or with JavaScript testing frameworks like Mocha or Jest.

What are Hapi plugins?

API Plugin is a component to define a function template for the API Parser and API Server to work with a third-party system. To define a new API plugin, complete the following steps. Tip: The system provides a built-in ServiceNow API Plugin and you can refer to it to write your own ones in the API Plugin Manager.

How do I test HTTP methods in Hapi?

The it () function is what will run your test. it () takes two parameters, a description of a successful test, and a function to run the test. You will note the use of inject on the server. inject uses Shot to inject a request directly into hapi's route handler. This is the magic which allows us to test HTTP methods.

What is the use case for use of Hapi?

Hapi is designed for creating robust, testable applications. To this end, Hapi includes the ability to test routes without having to actually start a server, completely avoiding the time overheads and added complexity of the TCP protocol.

Which testing frameworks can be used with Supertest?

One of the nice things about SuperTest is that while it can run tests without any additional tools, it can integrate nicely with other testing frameworks, as you'll see next. One of the better-known JavaScript testing frameworks, Mocha runs on both Node.js and the browser, making it useful for testing asynchronous functionality.

What is Supertest?

SuperTest provides a high-level abstraction for testing HTTP requests - perfect for APIs. If you have a Node.js application that runs an HTTP server (like an Express application), you can make requests using SuperTest directly without needing a running server.


2 Answers

Minimal code sample for testing written in js:

'use strict';

const Hapi = require('hapi');
const should = require('chai').expect
const request = require('supertest')


const server = new Hapi.Server();
server.connection({ port: 3000 });

server.route({
  method: 'GET',
  path: '/',
  handler: function (request, reply) {
    reply('Hello, world!');
  }
});

describe('server', function() {
  it('server', function(done) {
    request(server.listener).get('/').expect(200, function(err, resp) {
      should(resp.text).equal('Hello, world!')
      done()
    })
  })
})

In case of "hapi": "^16" works as is.

In case of "hapi": "^8.1.0" you need to manually run server.start() berfore request

like image 194
kharandziuk Avatar answered Jan 04 '23 04:01

kharandziuk


Estus' answer worked. I needed to export the hapi.Server in my outermost class, app.js. Then pass its listener property to tape.

And then I had to use tape.onFinish( () => server.stop() ); to stop the server at the end of my tests.

like image 20
Richard Avatar answered Jan 04 '23 03:01

Richard