I have created simple Mocha test. It works perfectly when Node "assert" module is used. I run it from command line (Mocha is installed as a global node module):
$ mocha myTest.js
․
1 test complete (6 ms)
The script looks like this:
var assert = require("assert")
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
})
})
})
Well, I tried to add Chai instead of assert library. I installed it first:
npm install chai
So, the directory node_modules has been created in my project. Great so far. Then, I altered the script to use Chai:
var chai = require("chai");
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
[1,2,3].indexOf(5).should.equal(-1);
expect([1,2,3].indexOf(5)).to.equal(-1);
assert.equal([1,2,3].indexOf(5),-1);
})
})
});
It does not work, Mocha test fails with TypeError:
TypeError: Cannot call method 'equal' of undefined
I assume Chai did not define should so it is undefined.
How is this possible?
How can I make my tests run with Chai? I have tried to install Chai globally with no effect. I also ran the script with -r chai with no effect as well.
Apparently, Chai module is loaded, but does not define the variables (Object.prototype properties). How can I fix this?
var expect = require('chai').expect;
That will get your expect calls working. However, you also have a should call which comes from a different library entirely, so change
[1,2,3].indexOf(5).should.equal(-1);
to
expect([1,2,3].indexOf(5)).to.equal(-1);
Related
I'm trying to use the methods beforeAll and afterAll of jasmine, to create a suite of tests with frisby.js, because actually, frisby doesn't have a support for this methods. So, this is what I'm trying to do:
var frisby = require('frisby');
describe("setUp and tearDown", function(){
beforeAll(function(){
console.log("test beforeAll");
});
afterAll(function(){
console.log("afterAll");
});
//FRISBY TESTS
}); //end of describe function
If I change the methods before/afterAll to before/afterEach, is working, but when I'm using before/afterAll this error appears on console:
Message:
ReferenceError: beforeAll is not defined
Stacktrace:
ReferenceError: beforeAll is not defined
I have the jasmine version 2.3.2 installed on my project, so, I don't know what I need to do to integrate this method.
Use the jasmine library not the jasmine-node library. The second one does not support beforeAll and afterAll methods.
1- npm install -g jasmine
2- jasmine init
3- write the test in the spec folder:
describe("A spec using beforeAll and afterAll", function() {
var foo;
beforeAll(function() {
foo = 1;
});
afterAll(function() {
foo = 0;
});
it("sets the initial value of foo before specs run", function() {
expect(foo).toEqual(1);
foo += 1;
});
it("does not reset foo between specs", function() {
expect(foo).toEqual(2);
});
});
4- Run the tests --> jasmine
The current version of frisby doesnt suport this kind of setup. The community, like myself is eager to this feature like in this issue describes.
The team is working on this feature, but it will come in version 2 of the package that is in the way for more than a year now. More info at this link.
I'm using the expect.js library with my mocha unit tests. Currently, I'm requiring the library on the first line of each file, like this:
var expect = require('expect.js');
describe('something', function () {
it('should pass', function () {
expect(true).to.be(true); // works
});
});
If possible, I'd like to remove the boilerplate require code from the first line of each file, and have my unit tests magically know about expect. I thought I might be able to do this using the mocha.opts file:
--require ./node_modules/expect.js/index.js
But now I get the following error when running my test:
ReferenceError: expect is not defined
This seems to make sense - how can it know that the reference to expect in my tests refers to what is exported by the expect.js library?
The expect library is definitely getting loaded, as if I change the path to something non-existent then mocha says:
"Error: Cannot find module './does-not-exist.js'"
Is there any way to accomplish what I want? I'm running my tests from a gulp task if perhaps that could help.
You are requiring the module properly but as you figured out, the symbols that the module export won't automatically find themselves into the global space. You can remedy this with your own helper module.
Create test/helper.js:
var expect = require("expect.js")
global.expect = expect;
and set your test/mocha.opts to:
--require test/helper
While Louis's answer is spot on, in the end I solved this with a different approach by using karma and the karma-chai plugin:
Install:
npm install karma-chai --save-dev
Configure:
karma.set({
frameworks: ['mocha', 'chai']
// ...
});
Use:
describe('something', function () {
it('should pass', function () {
expect(true).to.be(true); // works
});
});
Thanks to Louis answer and a bit of fiddling around I sorted out my test environment references using mocha.opts. Here is the complete setup.
My project is a legacy JavaScript application with a lot of "plain" js files which I wish to reference both in an html file using script tags and using require for unit testing with mocha.
I am not certain that this is good practice but I am used to Mocha for unit testing in node project and was eager to use the same tool with minimal adaptation.
I found that exporting is easy:
class Foo{...}
class Bar{...}
if (typeof module !== 'undefined') module.exports = { Foo, Bar };
or
class Buzz{...}
if (typeof module !== 'undefined') module.exports = Buzz;
However, trying to use require in all the files was an issue as the browser would complain about variables being already declared even when enclosed in an if block such as:
if (typeof require !== 'undefined') {
var {Foo,Bar} = require('./foobar.js');
}
So I got rid of the require part in the files and set up a mocha.opts file in my test folder with this content. The paths are relative to the root folder:
--require test/mocha.opts.js
mocha.opts.js content. The paths are relative to the location of the file:
global.assert = require('assert');
global.Foo = require("../foobar.js").Foo;
global.Bar = require("../foobar.js").Bar;
global.Buzz = require("../buzz.js");
I have a hard time connecting Mocha to RequireJS based application, may be You'll be able to come up with something :). After many hours when I've been trying to load AMD modules and simply console.log some 'fired' info that the module has been loaded... nothing happend had happened - the program just ended and printed out some mocha info.
var facade = requirejs(['../../public/js/scripts/widgets/widgets/article/main.js'],
function(mod) {
console.log('fired')
});
// run with: $ mocha -u tdd test.js --reporter spec
and than I've come up with the idea to fire just this to test callbacks:
setTimeout((function() {
console.log('fired');
}), 5000);
// run with: $ mocha -u tdd test.js --reporter spec
also didn't work. So finally I've run both with
$ node test.js
and finally it worked. So question is than: How to run Mocha test with callbacks handling, as those are essential for AMD testing?
The way you are doing it, mocha is not going to do anything with your file because it does not see a test suite in it. RequireJS is scheduled to call the callback but mocha exits before this has a chance to happen. Same with your timeout example.
The following gives you an example.
File test.js:
'use strict';
var requirejs = require("requirejs");
requirejs.config({
baseUrl: '.',
nodeRequire: require
});
suite('Something', function(){
var foo;
suiteSetup(function (done){
// This saves the module foo for use in tests. You have to use
// the done callback because this is asynchronous.
requirejs(['foo'],
function(mod) {
console.log("fired!");
foo = mod;
done();
});
});
suite('blah', function(){
test('blah', function(){
if (foo.test !== "test")
throw new Error("failed!");
});
});
});
File foo.js:
define(function () {
return {test: "test"};
});
When you run:
mocha -u tdd test.js
You'll see that the callback is fired and the test passes.
For the benefit of people reading this question and confused by the use of suite, suiteSetup, test... Mocha supports multiple interfaces. The code here is using the TDD interface (the OP invokes Mocha with -u tdd), which exports suite, suiteSetup, test, etc. In the default BDD interface, the equivalents are describe, before and it, respectively.
I have configured related boilerplate for using mocha in environment of RequireJS. It may be not exact what you want, but it may be helpful.
https://github.com/x2es/boilerplate-karma-mocha-chai-requirejs
One more note - assuming that your script placed in "/public" it makes sense to test it in browser environment instead nodejs. For this purposes you should to look at some test-runner like JsTestDriver (https://code.google.com/p/js-test-driver/) or karma-runner (http://karma-runner.github.io/). Or another...
In snipped provided in karma documentation (http://karma-runner.github.io/0.8/plus/RequireJS.html)
var tests = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
if (/Spec\.js$/.test(file)) {
tests.push(file);
}
}
}
requirejs.config({
// Karma serves files from '/base'
baseUrl: '/base/src',
paths: {
'jquery': '../lib/jquery',
'underscore': '../lib/underscore',
},
shim: {
'underscore': {
exports: '_'
}
},
// ask Require.js to load these files (all our tests)
deps: tests,
// start test run, once Require.js is done
callback: window.__karma__.start
});
introduced way when we force requirejs to preload all necessary spec-files using
require.config({
deps: ['array', 'of', 'our', 'spec', 'files']
})
In this environment each spec-file should be a regular RequireJS module.
Example of test spec for such environment:
define(['chai'], function(chai) {
var expect = chai.expect;
describe('bootstrap', function() {
it('should...', function() {
expect('a').to.equal('a');
});
});
});
I'm facing an issue while trying to get javascript unit tests to work at the command line using qunit.
Here's some sample code to reproduce the error:
file util.js:
function abc() {
return 'abc';
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
abc: abc
};
}
file util-tests.js
var qunit = require("qunit");
test("Test abc function", function () {
equal(util.abc(), 'abc');
});
With these files, I can run tests using the following command (gives a table-like output in the shell with the test results):
qunit -c util:util.js -t util-tests.js
Now it breaks if I add the following to util.js
$(document).ready(function () {
/* some code here */
});
Here's the error output:
qunit -c util:util.js -t util-tests.js
Testing /home/mfrere/jstst/util.js ... [Error: Uncaught exception in child process.]
same problem with:
var a = $;
or:
var a = document;
So this makes me think that I need to import jQuery somehow, so I thought about adding jquery.js as a dependency to the command, like this:
qunit -c util:util.js -t util-tests.js -d jquery.js
The above command gives me the same 'Uncaught exception' error, even if util.js doesn't contain any reference to '$'.
I'll probably need to do something else to get qunit to recognize 'document' as well, but I don't know what or how.
Now here's my question: what should I do to get this to work? It is important to keep in mind I want to test my files at the command line, not in a browser.
Just in case I did something wrong in the setup process, this is how I installed node/qunit (under ubuntu):
git clone git://github.com/creationix/nvm.git ~/.nvm
in .bashrc, I added the following line:
source ~/.nvm/nvm.sh
picked a specific version of node
nvm install v0.9.2
nvm alias default 0.9
and installed qunit
npm install -g qunit
finally I had to add this in .bashrc as well:
export NODE_PATH=~/.nvm/v0.9.2/lib/node_modules
You haven't imported jQuery:
$ = require('jquery'),
jQuery = require('jquery');
If you're using browserify, change that to 'jquery-browserify'.
I'm new at node.js and the framework Mocha for unit testing, but I've created a couple of tests in cloud9 IDE just to see how it works. The code looks like this:
var assert = require("assert");
require("should");
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
});
});
});
describe('Array', function(){
describe('#indexOf()', function(){
it('should return the index when the value is present', function(){
assert.equal(1, [1,2,3].indexOf(2));
assert.equal(0, [1,2,3].indexOf(1));
assert.equal(2, [1,2,3].indexOf(3));
});
});
});
The tests work if I type mocha in the console, but the IDE shows warnings in the lines where "describe" and "it" are because it says that the variable has not been declared ("undeclared variable").
I wonder what should I do these tests to avoid the warnings.
Thanks.
In cloud9 you can add a hint for globals as a comment at the top of the file and it will remove the warnings.
e.g.
**/* global describe it before */**
var expect = require('chai').expect;
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
expect(true).to.equal(true);
})
})
})
That's because mocha "executable" wraps your test in requires needed to use mocha functions (describe, and it). Take a look at mocha and _mocha in your node_modules/mocha/bin directory.
On the other hand cloud9 tries to resolve all symbols using a pure node executable, so you have to require everything by hand.