2

I'm using yeoman, grunt, mocha. I want to do BDD so I make basic unit test and run grunt test in console, which gives me ReferenceError: can't find variable: Creature opening test/index.html in browser works as it should.

This is my creature.js file in app/scripts:

'use strict';
var Creature = (function () {
    function Creature(name) {
        this.name = name;
    }
    Creature.prototype.sayHello = function (message) {
        return this.name + ' ' + message;
    };
    Creature.prototype.eat = function (item){
        return this.name + ' is eating ' + item;
    }
    return Creature;
})();

This is my test/index.html

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Mocha Spec Runner</title>
    <link rel="stylesheet" href="bower_components/mocha/mocha.css">
</head>
<body>
    <div id="mocha"></div>
    <script src="bower_components/mocha/mocha.js"></script>
    <script>mocha.setup('bdd')</script>
    <script src="bower_components/chai/chai.js"></script>
    <script>
        var assert = chai.assert;
        var expect = chai.expect;
        var should = chai.should();
    </script>

    <!-- include source files here... -->
    <script src="../app/scripts/creature.js"></script>
    <!-- include spec files here... -->
    <script src="spec/test.js"></script>

    <script>mocha.run()</script>
</body>
</html>

This is my test/spec/test.js file:

/* global describe, it */

(function () {
    'use strict';

    describe('Creature', function () {
        describe('Comunnications', function () {
            it('should say <name> hi', function () {
                var creature = new Creature('test');
                expect(creature.sayHello('hi')).to.equal('test hi');
            });
            it('should say <name> is eating <item>', function () {
                var creature = new Creature('test');
                expect(creature.eat('pear')).to.equal('test is eating pear');
            });
        });
    });
})();

Console log:

Running "copy:styles" (copy) task

Done, without errors.

Running "autoprefixer:dist" (autoprefixer) task

Running "connect:test" (connect) task
Started connect web server on http://localhost:9001

Running "mocha:all" (mocha) task
Testing: http://localhost:9001/index.html

  ..

  0 passing (113ms)
  2 failing

  1) Creature Comunnications should say <name> hi:
     ReferenceError: Can't find variable: Creature
      at http://localhost:9001/spec/test.js:9
      at http://localhost:9001/bower_components/mocha/mocha.js:4263
      at http://localhost:9001/bower_components/mocha/mocha.js:4635
      at http://localhost:9001/bower_components/mocha/mocha.js:4694
      at next (http://localhost:9001/bower_components/mocha/mocha.js:4561)
      at http://localhost:9001/bower_components/mocha/mocha.js:4570
      at next (http://localhost:9001/bower_components/mocha/mocha.js:4514)
      at http://localhost:9001/bower_components/mocha/mocha.js:4538
      at timeslice (http://localhost:9001/bower_components/mocha/mocha.js:5531)

  2) Creature Comunnications should say <name> is eating <item>:
     ReferenceError: Can't find variable: Creature
      at http://localhost:9001/spec/test.js:13
      at http://localhost:9001/bower_components/mocha/mocha.js:4263
      at http://localhost:9001/bower_components/mocha/mocha.js:4635
      at http://localhost:9001/bower_components/mocha/mocha.js:4694
      at next (http://localhost:9001/bower_components/mocha/mocha.js:4561)
      at http://localhost:9001/bower_components/mocha/mocha.js:4570
      at next (http://localhost:9001/bower_components/mocha/mocha.js:4514)
      at http://localhost:9001/bower_components/mocha/mocha.js:4538
      at timeslice (http://localhost:9001/bower_components/mocha/mocha.js:5531)


>> 2/2 tests failed (0.11s)
Warning: Task "mocha:all" failed. Use --force to continue.

Aborted due to warnings.


Execution Time (2014-06-08 14:40:23 UTC)
concurrent:test     3s  ■■■■■■■■■■■■■■■ 32%
connect:test     447ms  ■■■ 5%
mocha:all         5.9s  ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 63%
Total 9.4s

Perhaps it has to do with the reference to ../app/scripts/creature.js when running through phantomjs it has a different path compared to using it in a real browser?

EDIT

It seems like grunt test opens the wrong path to test on. It seems to open root/index.html When it opens... I got it to work by changing the path to the creature.js (removed the app/)

<!-- include source files here... -->
<script src="../scripts/creature.js"></script>

However when running grunt test it now works, but opening the test/index.html file it now gives me the error ReferenceError: Creature is not defined in firebug console.

Do I do something wrong or is that de correct behaviour? Anything I can do to make it work both ways?

I discovered where the issue was by changing the gruntfile.js changed test:options:open to true.

// The actual grunt server settings


connect: {
        options: {
            port: 9000,
            open: true,
            livereload: 35729,
            // Change this to '0.0.0.0' to access the server from outside
            hostname: 'localhost'
        },
        livereload: {
            options: {
                ...
            }
        },
        test: {
            options: {
                open: false,
                port: 9001,
                middleware: function(connect) {
                    return [
                        connect.static('.tmp'),
                        connect.static('test'),
                        connect().use('/bower_components', connect.static('./bower_components')),
                        connect.static(config.app)
                    ];
                }
            }
        },
        dist: {
            ...
            }
        }
    }

Thanks in advance!

Possibly related to Running Mocha on the command line and Including a file

Community
  • 1
  • 1
Anima-t3d
  • 3,431
  • 6
  • 38
  • 56

3 Answers3

0

This is probably because of this line. connect.static(config.app). Running it on the commandline, it runs connect, and sets the root/base path (where it reads the file) to app and test. So if you remove app it works for commandline, however if you are running it as a file, it is relative, hence needing 'app'

  • So what do you suggest as a solution? Making changes in `connect.static(config.app)` makes the testrunner pass with 0 passes (so it does not run the actual test). I do not see why it can not run both the console runner and the actual page without having to make a change in one or the other each time. – Anima-t3d May 22 '15 at 15:58
-1

probably you call

<script>mocha.run()</script>

when DOM is not ready yet try this

<script>
if( document.readyState === "complete" ) {
   var creature = new Creature('test'); 
   alert(creature .name);
   //mocha.run()
}
</script>

or with jQuery

$(function() {
var creature = new Creature('test'); 
   alert(creature .name);
   //mocha.run()
});
volkinc
  • 2,143
  • 1
  • 15
  • 19
  • Nope, if I change it to this it'll break test in browser (shows white page) and still give reference error in console. – Anima-t3d Jun 08 '14 at 15:18
  • Without the if document.readyState it fires and shows an alert in the browser with the correct name. Console keeps giving same error. – Anima-t3d Jun 08 '14 at 15:26
  • you told without document.readyState, what is happening with? – volkinc Jun 08 '14 at 15:28
  • document.readyState does not work. Anything put in the `if(document.readyState == "complete")` does not fire. – Anima-t3d Jun 08 '14 at 15:34
  • I see. But you problem is that Creature object was not loaded on a moment when you call it. if you use jquery try $(function() { var creature = new Creature('test'); alert(creature .name); //mocha.run() }); – volkinc Jun 08 '14 at 15:40
  • I'm not using jquery, but I added it in and tried that and it shows the correct name of the creature when I check in the browser. Console still output same errors whether or not I `mocha.run()` when page is ready. – Anima-t3d Jun 08 '14 at 15:52
-1

Have you tried putting

<script src="../app/scripts/creature.js"></script>

before

<script src="bower_components/mocha/mocha.js"></script>

It looks like the var isn't defined and probably what volkinc was after with his response.

  • Thanks for helping. When I put my creature.js first thing in the body. My browser test will still work, but the console test passes doing no tests: `0 passing (1ms) >> 0 passed! (0.00s) Done, without errors.` – Anima-t3d Jun 12 '14 at 09:39
  • Have you tried removing 'var Creature=' from creature.js? – crazycharlie Jun 13 '14 at 11:32
  • After trying your fix just now (which didn't work) I found out it has to do with my connection to the test server in gruntfile.js When opening html file straight all links are correct, but when opening it via `grunt test` it links wrong to the creature.js, I think due to it opening the wrong page to test. I'll post an update in a bit – Anima-t3d Jun 13 '14 at 11:57
  • I updated the original post, can you tell me how to make it work both ways or if it's the correct behaviour to not be able to open test/index.html straight? – Anima-t3d Jun 13 '14 at 12:15
  • Have you tried setting the port to 0 or '?' so the server will choose a port if that port is unavailable? Set the hostname to '*' to make it available anywhere. – crazycharlie Jun 17 '14 at 11:51
  • Changing hostname to '*' makes it go to 0.0.0.0 which mocha can not find (browser also can not find it). – Anima-t3d Jun 19 '14 at 20:16
  • This may be helpful - https://www.npmjs.org/package/grunt-mocha-runner. Otherwise, I'm not sure what else to try. – crazycharlie Jun 20 '14 at 14:41
  • Why the downvote? I provided reference and apparently this question was never answered anyway? – crazycharlie Sep 02 '14 at 13:54
  • I did not downvote it, but it could be because it does not solve the question. I'm still out of the country and will try to provide an answer to my own question for future references. Thanks anyway for your help. – Anima-t3d Sep 04 '14 at 03:29
  • Thanks, Anima-t3d. Someone did and not sure why. Sounds like you figured it out. – crazycharlie Sep 05 '14 at 12:12