Writing mocha test for nodejs - node.js

I am a beginner to nodejs, I need to know how to write a mocha test for nodejs for variable definitions.
for example,
if i had a object like this,
var objectName = {
fileName : '',
filePath : ''
}
Then how can write a mocha test for this variable definition. Please help me to write a test code. Thanks in advance!

I don't test this kind of stuff usually, but can make something like (using chai.expect) :
var obj = {
name:''
};
describe('My object definition', function(){
it('should give me an empty name', function(){
expect(obj.name).to.equals('');
});
});

Related

Is DB a reserved word in Node.js

I am building some tests with mocha and chai(expect).
Keeping it simple as I am learning about testing methodology as I go along.
I have a mysql db layer in a config file.
Testing the db parameters, I ran into a weird issue.
These db parameters test fine:
host= 'localhost',
user='foo',
password='bar',
The tests:
var expect = require('chai').expect;
var db = require('../db/config.ini');
describe('Database Access', function() {
it('HOST parameter should be a string', function() {
expect(host).to.be.a('string');
});
it('USER parameter should be a string', function() {
expect(user).to.be.a('string');
});
it('PASSWORD parameter should be a string', function() {
expect(password).to.be.a('string');
});
it('DB parameter should be a string', function() {
expect(db).to.be.a('string');
});
it('HOST parameter should equal localhost', function() {
expect(host).to.equal('localhost');
});
it('USER parameter should equal foo', function() {
expect(user).to.equal('foo');
});
it('PASSWORD parameter should equal bar', function() {
expect(password).to.equal('bar');
});
it('DB parameter should equal thatone', function() {
expect(context).to.equal('thatone');
});
});
When I add the database to choose,
db='thatone';
The test fails the parameter because it reads it as an object.
1) Database Access DB parameter should be a string:
AssertionError: expected {} to be a string
at Context.<anonymous> (test/db_tests.js:21:20)
If I change the variable name to "context" the test passes as expected.
I'm wondering if there is something obvious I am missing about using "db" as a variable.
UPDATE
Really stupid, novice level mistake.
So focused on learning testing methodology I didn't realize I had created the
'db' var as a require to the 'ini' and then referenced it later as though it was unique.
Really dumb. Rushing through this recklessly to get to a destination, and failing to follow some good methodology.
The result of executing this is not a string:
var db = require('../db/config.ini');
It seems you are trying to get a file in some INI dialect to be meaningfully interpreted by Node. Node does not support this by default. If you do not get an error while loading it, the most likely reason is that the text you have in there happens to also be valid JavaScript but since INI files do not contain proper code to export something (i.e. the file does not contain exports.db = "something" or module.exports = { ... } or something similar), then the module has the value {}.
You need to add one of the multiple npm packages that will automatically interpret an INI file and provide a meaningful value. I cannot recommend one as I don't use INI files in my software but you can search npm for a package that will perform the translation for you.

Mocha assertion error: expected {} to be a string

I've been beating my head all morning on this and I'm pretty sure I'm just missing something simple. It appears I'm getting a new object ({}) for a return value when I'm expecting a string, but even if I hard code a string for a return value I get the same error.
I've worked through the examples found here with no trouble. My package.json is set to test properly (or at least I don't think that's the problem, but I can post it as well if it'll help troubleshoot my problem). I'm new-ish to Node.js (but well experienced with JS) & just learning Mocho & Chai.
What am I missing? Why am I getting what appears to be an empty object when I should be getting a string? What's causing the test to fail?
I've written a simple API to get the username from a host PC:
const username = require('username');
exports.getUserName = function() {
console.log(username.sync());
return username.sync();
};
And I've written a test using Mocha & Chai:
var expect = require("chai").expect;
var getUserName = require('./username.js');
describe("User name API", function () {
it("Returns a string with the user's name", function () {
expect(getUserName).to.be.a('string');
});
});
Here's the error that's returned when I run the test with npm test:
> sbserialwidget#0.0.1 test C:\deg\node_modules\sbSerialWidget
> mocha --reporter spec
running
User name API
1) Returns a string with the user's name
0 passing (13ms)
1 failing
1) User name API Returns a string with the user's name:
AssertionError: expected {} to be a string
at Context.<anonymous> (C:\deg\node_modules\sbSerialWidget\test\username.js:6:29)
at callFn (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runnable.js:334:21)
at Test.Runnable.run (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runnable.js:327:7)
at Runner.runTest (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:429:10)
at C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:535:12
at next (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:349:14)
at C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:359:7
at next (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:285:14)
at Immediate._onImmediate (C:\deg\node_modules\sbSerialWidget\node_modules\mocha\lib\runner.js:327:5)
If I change the test to expect an object, the test works: expect(getUserName).to.be.an('object');.
However if I do a console.log(typeof username.sync()); it says it's a string.
What do I need to do to fix this?
Edit for solution:
Here's the code that I eventually got to work. I think part of the problem was a path issue (I'm in a Windows environment), partly me simply not quite understanding what needed to be done, and finally me not understanding how to call the function properly in the test (see below).
Here's the modified username.js code:
const username = require('username');
exports.getUserName = function() {
console.log(username.sync());
return username.sync();
}
Here's the modified usernametest.js:
var expect = require("chai").expect;
//here's where one point of confusion was, I was trying to call the original getUserName()
//function, but it's been turned into a variable called username
var username = require('..\\js\\username.js').getUserName;
describe("User name API", function () {
it("returns a string with the user's name", function () {
//so here, instead of calling username.getUserName(), I call username()
//instead. Voila, it works...
expect(username()).to.be.a('string');
});
});
you are not executing the function
change
expect(getUserName).to.be.a('string');
to
expect(getUserName()).to.be.a('string');
edit
I din't figure out that your are exporting an object
exports.getUsername = function(){...}
should be
expect(getUserName.getUserName()).to.be.a('string');
thanks to #robertklep

What is exports.install in node js?

Hi I found a framework where they use a lot this pattern.
exports.install = function(){
//code
}
but usually you see this pattern in nodejs
module.exports = {
//code
}
Is this the same thing or is this something else ?
exports is the object corresponding to module.exports before you do anything to it. I think it's due to some legacy code, but basically folks use module.exports if they want to replace the whole object with their own object or a function, while they use exports if they just want to hang functions off the module. It's a little confusing at first, but essentially exports.install just means that calling code would do something like:
const mod = require('that-module');
mod.install(params, callback); // call that function
The framework you're looking at is probably using it as part of a bootstrapping process, afaik it doesn't have significance to the node engine itself.
Yes, it is the same thing. You can use one of 2 ways to setup your code.
The different thing is memory. They point to same memory. You can think exports like a variable and you can not use this way to export your module:
Given this module:
// test.js
exports = {
// you can not use this way to export module.
// because at this time, `exports` points to another memory region
// and it did not lie on same memory with `module.exports`
sayHello: function() {
console.log("Hello !");
}
}
The following code will get the error: TypeError: test.sayHello is not a function
// app.js
var test = require("./test");
test.sayHello();
// You will get TypeError: test.sayHello is not a function
The correct way you must use module.exports to export your module:
// test.js
module.exports = {
// you can not use this way to export module.
sayHello: function() {
console.log("Hello !");
}
}
// app.js
var test = require("./test");
test.sayHello();
// Console prints: Hello !
So, it just is style of developer.

Unit test for node js

I am new to nodejs, and need to write unit test for a node project. I try to learn mocha and there are two questions:
when I write unit test for function A, in A it also use function B, so how can I mock an output for B?
how can I unit test these endpoints in app.js. like app.get, app.put.
can someone give me some suggestions or simple examples?
Can someone also give me some advice on writing unit test for nodejs, thanks so much.
Thanks so much everyone.
Answering Q1,
If the output of b method is used in a metheod, then you can make the test of b method first.
Otherwise you can prepare result of b in before section of your test method and use it in a method.
It depends on your approach of testing.
Answering Q2 -
You can use superagent for sending get or post request ...
Some code examples ...
require('should');
var assert = require("assert");
var request = require('superagent');
var expect = require('expect.js');
then,
describe('yourapp', function(){
before(function(){
// function start
start your server code
// function end
})
describe('server', function(){
describe('some-description', function(){
it('should return json in response', function(done){
request.post('http path')
.send(JSON.parse("your json"))
.end(function(res){
expect(res).to.exist;
expect(res.status).to.equal(200);
expect(res.text).to.contain('ok');
done();
});
})
});
})
after(function(){
//stop your server
})
});
Here done is an important aspect in a unit testing component for asynchronous method testing.
Some reference -
superagent
this blog post
Hope this will help you,
Thanks
Answering Q1,
If the funcitons in different modules,
You can use a mock tool : fremock
Using freemock You can do this:
your code
//function a exports in the module named mA
function a(){
return "1";
}
//function a exports in the module named mB
function b(){
a();
}
test code
var freemock = require('freemock');
freemock.start()
var mock_b = freemock.getMock('mB');
mock_b.setMethod({
"a":{
willReturn:"1"
}
})
freemock.end();
Some advice:
Mocha is good test framework for node.js .
For example,
Assert tool: should.js
Code coverage tool:istanbul
...
Mocha combines all this tools;
Here is a demo using Mocha:
your code(filename:mA.js)
//in the module named mA
function a(){
return true;
}
test code(filename:testmA.js)
var should = require('should');
beforeEach(function(){
//do something before testing
});
afterEach(function(){
//do something after testing
});
describe("test",function(){
describe("test1",function(){
it("if true",function(){
var mA = require('./mA');
var result = mA.a();
should.ok(result);
});
it("if false",function(){
//other test
});
});
describe("test2",function(){
it("test2-1",function(){
//other test
})
})
})
We should need run.js to start the test:
//run.js
var Mocha = require('mocha');
var mocha = new Mocha;
mocha.addFile(__dirname+'/test/testmA.js')
mocha.run();
The project dir tree is:
|- run.js
|
|- mA.js
|
|- test - testMA.js
Finally
Run this command:
istanbul cover run.js
Hope you enjoy!
I am recently involved in a node project where I have to run unit tests.
Eventually I wrote a small script runner for karma using NW.JS
This allowed me to access all node modules and run my tests on the server itself. I uploaded this project to github, Narma.
Right now it was only tested on a Mac

Mocha and ZombieJS

I'm starting a nodejs project and would like to do BDD with Mocha and Zombiejs. Unfortunately I'm new to just about every buzzword in that sentence. I can get Mocha and Zombiejs running tests fine, but I can't seem to integrate the two - is it possible to use Mocha to run Zombiejs tests, and if so, how would that look?
Just looking for "hello world" to get me started, but a tutorial/example would be even better.
Thanks!
Assuming you already have installed mocha, zombie and expect.js according to instructions, this should work for you:
// Put below in a file in your *test* folder, ie: test/sampletest.js:
var expect = require('expect.js'),
Browser = require('zombie'),
browser = new Browser();
describe('Loads pages', function(){
it('Google.com', function(done){
browser.visit("http://www.google.com", function () {
expect(browser.text("title")).to.equal('Google');
done();
});
});
});
Then you should be able to run the mocha command from your root application folder:
# mocha -R spec
Loads pages
✓ Google.com (873ms)
✔ 1 tests complete (876ms)
Note: If your tests keep failing due to timeouts, it helps to increase mocha's timeout setting a bit by using the -t argument. Check out mocha's documentation for complete details.
I wrote a lengthy reply to this question explaining important gotchas about asynchronous tests, good practices ('before()', 'after()', TDD, ...), and illustrated by a real world example.
http://redotheweb.com/2013/01/15/functional-testing-for-nodejs-using-mocha-and-zombie-js.html
if you want to use cucumber-js for your acceptance tests and mocha for your "unit" tests for a page, you can use cuked-zombie (sorry for the advertising).
Install it like described in the readme on github, but place your world config in a file called world-config.js
`/* globals __dirname */
var os = require('os');
var path = require('path');
module.exports = {
cli: null,
domain: 'addorange-macbook': 'my-testing-domain.com',
debug: false
};
Then use mocha with zombie in your unit tests like this:
var chai = require('chai'), expect = chai.expect;
var cukedZombie = require('cuked-zombie');
describe('Apopintments', function() {
describe('ArrangeFormModel', function() {
before(function(done) { // execute once
var that = this;
cukedZombie.infectWorld(this, require('../world-config'));
this.world = new this.World(done);
// this inherits the whole world api to your test
_.merge(this, this.world);
});
describe("display", function() {
before(function(done) { // executed once before all tests are run in the discribe display block
var test = this;
this.browser.authenticate().basic('maxmustermann', 'Ux394Ki');
this.visitPage('/someurl', function() {
test.helper = function() {
};
done();
});
});
it("something on the /someurl page is returned", function() {
expect(this.browser.html()).not.to.be.empty;
});

Resources