chernevik
chernevik

Reputation: 4000

test works in browser but not PhantomJS

I have a Mocha (Chai?) test of an Ajax request that works when using an HTML file as a test runner, but not when run from PhantomJS.

Karma is running other tests successfully.

My Questions:

Why is Karma failing?
How do I get this test to run in PhantomJS?

Karma reports:

PhantomJS 1.9.8 (Linux 0.0.0) MyAPI "before each" hook for "should parse fetched data as JSON" FAILED
    TypeError: 'undefined' is not a function (evaluating 'function(xhr) {
          this.requests.push(xhr);
        }.bind(this)')
        at [...]ajax_test_demo.test.js:22

The test file:

chai.should();

describe('MyAPI', function() {

  // var bike_app = new BikeApp();

  beforeEach(function() {
    this.xhr = sinon.useFakeXMLHttpRequest();

    this.requests = [];
    this.xhr.onCreate = function(xhr) {
      this.requests.push(xhr);
    }.bind(this);
  });

  afterEach(function() {
    this.xhr.restore();
  });

  it('should parse fetched data as JSON', function(done) {
      var data = { foo: 'bar' };
      var dataJson = JSON.stringify(data);

      myapi.get(function(err, result) {
          result.should.deep.equal(data);
          done();
      });

      this.requests[0].respond(200, { 'Content-Type': 'text/json' }, dataJson);
  });

});

Thoughts

Karma seems to be running Sinon, no complaint when sinon.useFakeXMLHttpRequest is called, but the object returned by that call lacks the onCreate method. Alas my JavaScript is weak and I don't know how to debug this.

The HTML test runner:

<!DOCTYPE html>
<html>
    <head>
        <title>Mocha Tests</title>
        <link rel="stylesheet" href="node_modules/mocha/mocha.css">
    </head>
    <body>
        <div id="mocha"></div>
        <script src="node_modules/mocha/mocha.js"></script>
        <!-- edit from source file -->
        <script src="node_modules/sinon/pkg/sinon.js"></script>
        <script src="node_modules/chai/chai.js"></script>
        <script>mocha.setup('bdd')</script>
        <script src="lib/myapi.js"></script>
        <script src="test/ajax_test_demo.test.js"></script>
        <script>
            mocha.run();
        </script>
    </body>
</html>

The Karma configuration:

'use strict';

var appConfig = require('./config');

module.exports = function(config) {
  config.set({

    basePath: '',

    frameworks: [
        'sinon',
        'mocha', 
        'chai', 
        'fixture',
    ],

  files: [
      'lib/*.js',
      'test/*.js',
      'test/*.html'
    ],

    preprocessors: appConfig.karma.preprocessors,    
    reporters: appConfig.karma.reporters,
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: appConfig.karma.autoWatch,
    browsers: appConfig.karma.browsers,
    singleRun: appConfig.karma.singleRun
  });
};

Misc

I'm working with this tutorial: https://www.airpair.com/javascript/posts/unit-testing-ajax-requests-with-mocha

Upvotes: 1

Views: 1124

Answers (2)

chernevik
chernevik

Reputation: 4000

I resolved this by upgrading PhantomJS from 1.9.7 to 2.0 and making some environment changes.

PhantomJS 2.0 is installed (on OSX) with sudo npm -g install phantomjs2.

(At this writing, there is no apt-get or npm path for upgrading PhantomJS. I'm building on Linux per this: http://phantomjs.org/build.html.)

Note that even after this upgrade, npm test was still running Phantom 1.9.8. I resolved that problem with export PHANTOMJS_BIN=/usr/local/bin/phantomjs (which would vary with where ever phantomjs is actually installed).

It is a hack solution -- I don't know why PhantomJS 2.0 works when 1.9.8 doesn't, nor why PHANTOMJS_BIN must be exported. But it works.

Upvotes: 1

jon skulski
jon skulski

Reputation: 2305

Function.prototype.bind is not available in Phantom 1.x, it was only implemented in 2.0+. It is a common problem. Upgrading or using a polyfill should solve this.

https://github.com/ariya/phantomjs/issues/10522

Upvotes: 2

Related Questions