Testing with Mocha and requirejs - javascript

Im trying to get a testing environment for JavaScript set up but I am having some trouble with Mocha and requirejs. So far I have installed Mocha and that works as it should because I have tested it with the sample test from the documentation. The problem arises when I try and require some of the modules I want to test. At the top of my test.js file I have this:
var assert = require("assert"),
door = require( '../../assets/scripts/modules/door' );
But i get this error message in the console.
ReferenceError: define is not defined
Its referring to the first line of the door.js file that is.
define(['../utils/templating/hogan', '../models/ApiCaller', 'Backbone'], function (hogan, ApiCaller) {
I have also tried requiring requirejs like so...
var assert = require("assert"),
requirejs = require( '../../assets/scripts/require' ),
door = require( '../../assets/scripts/modules/door' );
As you have probably guessed im new to testing JavaScript and any explanation or solution would be great.
Thanks.

See if this gist https://gist.github.com/michaelcox/3800736 is helpful for you.

Related

Reason for node module #kenjiuno/msgreader error: MsgReader is not a constructor

I'm unable to get even the first lines of the example code from the relatively popular #kenjiuno/msgreader for parsing Outlook .msg files to work. I've installed the module with npm successfully, and my code is:
const fs = require('fs')
const MsgReader = require('#kenjiuno/msgreader')
const msgFileBuffer = fs.readFileSync('./test-email.msg')
const testMsg = new MsgReader(msgFileBuffer)
But I get the error: "MsgReader is not a constructor".
A quick console log of MsgReader returns { default: [Function: MsgReader] }. I also tried doing it as a function (no 'new' keyword) which also produced an error.
The only difference between my code and the example code is that they use import (import MsgReader from '#kenjiuno/msgreader') whereas I've used require, but presumably that couldn't make a difference?
Any ideas anyone?
I ended up changing the require statement to add ["default"] which fixed the issue:
const MsgReader = require('#kenjiuno/msgreader')["default"]
I looked at the library code and made a guess based on the export statement using that 'default' syntax. Is this issue something to do with commonJS or something? If anyone can explain this to me that would be great!

export node module to local error

i am a newby on node.js. i want to parse a xml file into json .so i am trying to use bulebutton library from https://github.com/blue-button/bluebutton.js .
first i have installed the module by command npm install bluebutton and its created a node_modules folder with bluebutton module.
now i created a test.js file with following code
var bb = require('bluebutton');
var myRecord = bb.BlueButton('./asd.xml');
console.log(myRecord);
but its gave me an error that bluebutton is not define .please help me to figureout this problem thanks
REVISED ANSWER
From bluebuttonjs.com/docs, the require statement you use would return the BlueButton object, so bb represents said object, and it would be called like so
var myRecord = bb('someFile.xml');
However you might also note that they use fs to read the file before passing it. http://www.bluebuttonjs.com/docs/#parsing-node
PREVIOUS ANSWER (for wrong module)
According to their npm docs, you need to do
var bb = require('blue-button');
https://www.npmjs.com/package/blue-button

How to properly require modules from mocha.opts file

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");

NodeJS and Javascript (requirejs) dependency injection

I am currently using requirejs to manage module js/css dependencies.
I'd like to discover the possibilities of having node do this via a centralized config file.
So instead of manually doing something like
define([
'jquery'
'lib/somelib'
'views/someview']
within each module.
I'd have node inject the dependencies ie
require('moduleA').setDeps('jquery','lib/somelib','views/someview')
Anyway, I'm interested in any projects looking at dependency injection for node.
thanks
I've come up with a solution for dependency injection. It's called injectr, and it uses node's vm library and replaces the default functionality of require when including a file.
So in your tests, instead of require('libToTest'), use injectr('libToTest' { 'libToMock' : myMock });. I wanted to make the interface as straightforward as possible, with no need to alter the code being tested. I think it works quite well.
It's just worth noting that injectr files are relative to the working directory, unlike require which is relative to the current file, but that shouldn't matter because it's only used in tests.
I've previously toyed with the idea of providing an alternate require to make a form of dependency injection available in Node.js.
Module code
For example, suppose you have following statements in code.js:
fs = require('fs');
console.log(fs.readFileSync('text.txt', 'utf-8'));
If you run this code with node code.js, then it will print out the contents of text.txt.
Injector code
However, suppose you have a test module that wants to abstract away the file system.
Your test file test.js could then look like this:
var origRequire = global.require;
global.require = dependencyLookup;
require('./code.js');
function dependencyLookup (file) {
switch (file) {
case 'fs': return { readFileSync: function () { return "test contents"; } };
default: return origRequire(file);
}
}
If you now run node test.js, it will print out "test contents", even though it includes code.js.
I've also written a module to accomplish this, it's called rewire. Just use npm install rewire and then:
var rewire = require("rewire"),
myModule = rewire("./path/to/myModule.js"); // exactly like require()
// Your module will now export a special setter and getter for private variables.
myModule.__set__("myPrivateVar", 123);
myModule.__get__("myPrivateVar"); // = 123
// This allows you to mock almost everything within the module e.g. the fs-module.
// Just pass the variable name as first parameter and your mock as second.
myModule.__set__("fs", {
readFile: function (path, encoding, cb) {
cb(null, "Success!");
}
});
myModule.readSomethingFromFileSystem(function (err, data) {
console.log(data); // = Success!
});
I've been inspired by Nathan MacInnes's injectr but used a different approach. I don't use vm to eval the test-module, in fact I use node's own require. This way your module behaves exactly like using require() (except your modifications). Also debugging is fully supported.

How do you compile CoffeeScript in a Jakefile?

I would like to create a Jakefile which compiles some CoffeeScripts to install a NodeJS application.
How do you do that?
I tried with:
https://gist.github.com/1241827
but it's a weak approach, definitely not classy.
Any hints?
Approx snippet I have used:
var fs = require('fs')
var coffee = require('coffee-script')
// If you'd like to see compiled code..
// console.log(coffee.compile(fs.readFileSync('coffee.coffee')))
// ..otherwise
fs.writeFileSync('output.js', coffee.compile(fs.readFileSync('input.coffee')))
..assumes you have the coffee-script node module installed, of course.
Translated from this Cakefile of mine.

Categories