Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing a hapi service composed using glue #14

Closed
olistic opened this issue Feb 3, 2015 · 8 comments
Closed

Testing a hapi service composed using glue #14

olistic opened this issue Feb 3, 2015 · 8 comments
Labels
support Questions, discussions, and general support

Comments

@olistic
Copy link

olistic commented Feb 3, 2015

When I wasn't using glue to compose the server, the way I tested my code was pretty straight-forward. I exported the Hapi server instance from the index.js file and then, in the test modules, I required it and used the server.inject method to test the endpoints of my API.

However, using glue my index turned into something like this, with the server instance being available asynchronously:

index.js:

var Glue = require('glue');
var manifest = require('./config/manifest.json');
var options = {
    relativeTo: process.cwd() + '/lib/modules'
};

Glue.compose(manifest, options, function (err, server) {
    server.start(function () {
        server.log('info', 'Server running at: ' + server.info.uri);
    });
};

So now, trying to figure out how may be the best way to export that server variable to make it accessible to the test modules, I've come up with this solution. I don't know if I'm doing the right thing, so I'm seeking advice:

index.js:

var Glue = require('glue');
var manifest = require('./config/manifest.json');
var options = {
    relativeTo: process.cwd() + '/lib/modules'
};

var compose = function (callback) {
    Glue.compose(manifest, options, function (err, server) {
        if (!module.parent) {
            server.start(function () {
                server.log('info', 'Server running at: ' + server.info.uri);
            });
        }

        if (typeof callback !== 'undefined') {
            callback(null, server);
        }
    });
};

// If this module is not being required by another one, compose the server.

if (!module.parent) {
    compose();
}

module.exports = compose;

Then the index.js would be required from the tests this way:

test/whatever.js:

var composedServer;

require('../')(function (err, server) {
    composedServer = server;
});

Any opinions would be very appreciated.

Thanks!

Matias

@csrl csrl added the question label Feb 6, 2015
@dstevensio
Copy link

(not a glue or hapi contributor, just my 2 cents...)

If your endpoint functionality is all contained within the modules in lib/modules and your index.js literally just sets up the Glue compose work, I would avoid exporting/importing your server and instead replicate it in your tests. So your index.js would remain like so:

var Glue = require('glue');
var manifest = require('./config/manifest.json');
var options = {
    relativeTo: process.cwd() + '/lib/modules'
};

Glue.compose(manifest, options, function (err, server) {
    server.start(function () {
        server.log('info', 'Server running at: ' + server.info.uri);
    });
};

while your tests would be like this:

test/whatever.js:

var Glue = require('glue');
var manifest = require('../config/manifest.json');
var options = {
    relativeTo: process.cwd() + '/lib/modules'
};

Glue.compose(manifest, options, function (err, server) {
    server.start(function () {

      // tests here using server.inject as you did before

    });
};

That's assuming that there is no additional work happening in your index.js that you need to test. If you're just doing the calls to Glue there, the endpoints are being accurately tested in this method. It does add the overhead of changing references to the manifest in multiple places if changed in index.js so bear that in mind.

@olistic
Copy link
Author

olistic commented Feb 9, 2015

Yeah, my scenario is exactly as you described, so I will follow your advice and compose the server in the tests too. I think my index.js file has got a bit cluttered with my current solution, and it remains clearer with yours.

Thank you very much!

@csrl csrl closed this as completed Feb 10, 2015
@csrl csrl self-assigned this Feb 10, 2015
@nakardo
Copy link

nakardo commented Jul 3, 2015

I had the same issue recently, and composing the server inside a Promise worked well. It also gets along nicely with mocha by requiring it on the before hook.

@oviava
Copy link

oviava commented Jan 27, 2016

Glue.compose(manifest, options, (err, server) => {
  if (!module.parent) {
    server.start(() => {
      console.log('Server started on port:', server.info.uri);
    });
  } else {
    module.exports = server;
  }
});

think this is the cheapest way

@davidjamesstone
Copy link

Sorry for reviving this thread.

Glue's compose callback is not executed asynchrouously. This is similar to Joi.validate.

This can be quite confusing at first (or was it just me?) given most error-first callbacks in nodejs are executed async.

Given this, I think oviava's comment above this is the simpliest way to go.

@devinivy
Copy link
Member

devinivy commented Aug 3, 2016

I created a tool to specifically help with this: https://github.com/devinivy/labbable#with-glue

@pintocarlos
Copy link

The following article shows how to tests the plugins directly without having to depend on the server wrapped in the glue composer:
http://ideasintosoftware.com/unit-testing-hapi-plugins/

I think this is by far the cleanest solution to testing your plugins, routes, and handler responses in a decoupled manner.

@Marsup Marsup added support Questions, discussions, and general support and removed question labels Sep 21, 2019
@Marsup Marsup unassigned csrl Sep 21, 2019
@lock
Copy link

lock bot commented Jan 9, 2020

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
support Questions, discussions, and general support
Projects
None yet
Development

No branches or pull requests

9 participants