2

I am attempting to use the Intern test framework to automate testing of a simple REST API implemented with node.js and StrongLoop. StrongLoop provides an explorer web page that I have used to validate that the REST API is implemented and I can manually test the API from Postman.

The first API test I am attempting with intern.js retrieves the count of media objects in a collection. The HTTP method is GET, the URL is http://localhost:3000/api/media/count and the response is {"count": 2}.

When I run my intern.js test I receive an error "Error: Attempt to require unloaded module http".

I have a \tests sub-directory within my node.js application. My test case is media.js:

define([
    'intern!object',
    'intern/chai!assert'
], function (registerSuite, assert, media) {
    registerSuite({
        name: 'media',
        count: function() {
        var http = require("http");
        var request = http.request;
        request({
          url: "http://localhost:3000/api/media/count",
          method: "GET"
        }, function (error, response, body) {
          console.log("Status", response.statusCode);
          console.log("Headers", JSON.stringify(response.headers));
          console.log("Response received", body);
        });

        assert.strictEqual(body, '{"count": 2}',
            url + ' should return 2 items');
        }
    });
});

My intern.js configuration file is:

// Learn more about configuring this file at <https://github.com/theintern/intern/wiki/Configuring-Intern>.
// These default settings work OK for most people. The options that *must* be changed below are the
// packages, suites, excludeInstrumentation, and (if you want functional tests) functionalSuites.
define({
    // The port on which the instrumenting proxy will listen
    proxyPort: 9000,

    // A fully qualified URL to the Intern proxy
    proxyUrl: 'http://localhost:9000/',

    // Default desired capabilities for all environments. Individual capabilities can be overridden by any of the
    // specified browser environments in the `environments` array below as well. See
    // https://code.google.com/p/selenium/wiki/DesiredCapabilities for standard Selenium capabilities and
    // https://saucelabs.com/docs/additional-config#desired-capabilities for Sauce Labs capabilities.
    // Note that the `build` capability will be filled in with the current commit ID from the Travis CI environment
    // automatically
    capabilities: {
        'selenium-version': '2.41.0'
    },

    // Browsers to run integration testing against. Note that version numbers must be strings if used with Sauce
    // OnDemand. Options that will be permutated are browserName, version, platform, and platformVersion; any other
    // capabilities options specified for an environment will be copied as-is
    environments: [
        { browserName: 'internet explorer', version: '11', platform: 'Windows 8.1' },
        { browserName: 'internet explorer', version: '10', platform: 'Windows 8' },
        { browserName: 'internet explorer', version: '9', platform: 'Windows 7' },
        { browserName: 'firefox', version: '28', platform: [ 'OS X 10.9', 'Windows 7', 'Linux' ] },
        { browserName: 'chrome', version: '34', platform: [ 'OS X 10.9', 'Windows 7', 'Linux' ] },
        { browserName: 'safari', version: '6', platform: 'OS X 10.8' },
        { browserName: 'safari', version: '7', platform: 'OS X 10.9' }
    ],

    // Maximum number of simultaneous integration tests that should be executed on the remote WebDriver service
    maxConcurrency: 3,

    // Name of the tunnel class to use for WebDriver tests
    tunnel: 'SauceLabsTunnel',

    // The desired AMD loader to use when running unit tests (client.html/client.js). Omit to use the default Dojo
    // loader
    useLoader: {
        'host-node': 'dojo/dojo',
        'host-browser': 'node_modules/dojo/dojo.js'
    },

    // Configuration options for the module loader; any AMD configuration options supported by the specified AMD loader
    // can be used here
    loader: {
        // Packages that should be registered with the loader in each testing environment
        packages: [ 
        { name: 'app', location: '.' },
        ]
    },

    // Non-functional test suite(s) to run in each browser
    suites: [ 'tests/media' /* 'myPackage/tests/foo', 'myPackage/tests/bar' */ ],

    // Functional test suite(s) to run in each browser once non-functional tests are completed
    functionalSuites: [ /* 'myPackage/tests/functional' */ ],

    // A regular expression matching URLs to files that should not be included in code coverage analysis
    excludeInstrumentation: /^(?:tests|node_modules)\//
});

I run the test using the command `c:\Repositories\app>intern-client config=tests/intern' and the below console output is produced:

c:\Repositories\app>intern-client config=tests/intern
FAIL: main - media - count (0ms)
Error: Attempt to require unloaded module http.request
  at contextRequire  <D:\Users\username\AppData\Roaming\npm\node_modules\inte
rn\node_modules\dojo\dojo.js:255:12>
  at req  <D:\Users\username\AppData\Roaming\npm\node_modules\intern\node_mod
ules\dojo\dojo.js:30:10>
  at Test.registerSuite.count [as test]  <tests\media.js:23:27>
  at Test.run  <D:\Users\username\AppData\Roaming\npm\node_modules\intern\lib
\Test.js:169:19>
  at <D:\Users\username\AppData\Roaming\npm\node_modules\intern\lib\Suite.js:
237:13>
  at signalListener  <D:\Users\username\AppData\Roaming\npm\node_modules\inte
rn\node_modules\dojo\Deferred.js:37:21>
  at Promise.then.promise.then  <D:\Users\username\AppData\Roaming\npm\node_m
odules\intern\node_modules\dojo\Deferred.js:258:5>
  at runTest  <D:\Users\username\AppData\Roaming\npm\node_modules\intern\lib\
Suite.js:236:46>
  at <D:\Users\username\AppData\Roaming\npm\node_modules\intern\lib\Suite.js:
249:7>
  at process._tickCallback  <node.js:419:13>
1/1 tests failed
1/1 tests failed

---------------|-----------|-----------|-----------|-----------|
File           |   % Stmts |% Branches |   % Funcs |   % Lines |
---------------|-----------|-----------|-----------|-----------|
   tests\      |     33.33 |       100 |     66.67 |     33.33 |
      media.js |     33.33 |       100 |     66.67 |     33.33 |
---------------|-----------|-----------|-----------|-----------|
All files      |     33.33 |       100 |     66.67 |     33.33 |
---------------|-----------|-----------|-----------|-----------|

My understanding is that the http module is a core module automatically installed with node.js, however I wonder if intern.js, although node-based, does not permit access to the core modules without additional configuration. This seams reasonable, however I have looked at the intern.js tutorial and the intern.js configuration guide, but have not found a way to add a reference or dependency such that the test case is able to load the node.js http module successfully. I am new to intern.js, so expect that I have not configured it or the test correctly.

I welcome any input/insight to what I am doing wrong.

Best Regards,

MW

1
  • One additional clarification: for this initial step, I am trying to test the REST API without any UI client component, so I am looking for a solution that does not rely on browsers or browser emulation. That is why I thought to use the node.js HTTP module. Commented Oct 8, 2014 at 21:55

1 Answer 1

8

Intern runs its tests in an AMD environment, so require is the AMD loader's require, not Node's, hence your error.

To load Node modules, use the intern/dojo/node! AMD plugin and include them in your module's dependencies, e.g.:

define([
    ...,
    'intern/dojo/node!http'
], function (..., http) {
    // Now http contains the exports of Node's http module
});

This is documented in Intern's User Guide under Testing CommonJS Modules.

Sign up to request clarification or add additional context in comments.

1 Comment

Maybe important to note: This does not only work with standard node modules as http but with any npm module.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.