EzDevInfo.com

should.js

BDD style assertions for node.js -- test framework agnostic

Where should unit tests be placed in Meteor?

Is there a place where my tests can live without being run by Meteor?

I just started my first Meteor project, and began by writing unit tests with Mocha and should.js. Though mocha runs without a problem, the tests prevent Meteor from starting up since it has issues using node's require instead of __meteor_bootstrap__.require (full error message).

That being said, Meteor should not be running my tests! According to the Meteor documentation, code can only be placed on the client, server, or both. Unit test suites do no belong in these categories, and I am not the only person confused by Meteor's lack of a well-defined location for placing automated tests.

Right now, my tests are kept in server/test/, with the contents of each file wrapped in the block:

if (typeof(Meteor) === 'undefined') { ... }

While this works, it does not feel elegant. Do you have any other suggestions for structuring your tests with your Meteor app?

Update: in lieu of explicit instructions in the Meteor docs, I followed the Rails folder conventions (4th paragraph), using a folder called test for storing my testing assets. I later moved this to server/test since I did not want it loaded on the client.


Source: (StackOverflow)

Chai, Mocha: Identify should assertion

I'm using mocha and chai as assertions.

I have several assertions in my spec

Exp1.should.be.true Exp2.should.be.true Exp3.should.be.true

If one of them fails mocha writes "expected false to be true", it there a way to identify them?

With expect I can do it: expect(Exp1, 'Exp1').to.be true

Is smth like this possible with should?


Source: (StackOverflow)

Advertisements

Mocha, should.js and asserting an exception

I have a file app.coffee:

class TaskList

class Task
    constructor: (@name) ->
        @status = 'incomplete'
    complete: ->
        if @parent? and @parent.status isnt 'completed'
          throw "Dependent task '#{@parent.name}' is not completed."
        @status = 'complete'
        true
    dependsOn: (@parent) ->
        @parent.child = @
        @status = 'dependent'

# Prepare scope stuff
root = exports ? window
root.TaskList = TaskList
root.Task = Task

and a file called test/taskTest.coffee:

{TaskList, Task} = require '../app'
should = require 'should'

describe 'Task Instance', ->
    task1 = task2 = null
    it 'should have a name', ->
        something = 'asdf'
        something.should.equal 'asdf'
        task1 = new Task 'feed the cat'
        task1.name.should.equal 'feed the cat'
    it 'should be initially incomplete', ->
        task1.status.should.equal 'incomplete'
    it 'should be able to be completed', ->
        task1.complete().should.be.true
        task1.status.should.equal 'complete'
    it 'should be able to be dependent on another task', ->
        task1 = new Task 'wash dishes'
        task2 = new Task 'dry dishes'
        task2.dependsOn task1
        task2.status.should.equal 'dependent'
        task2.parent.should.equal task1
        task1.child.should.equal task2
    it 'should refuse completion it is dependent on an uncompleted task', ->
        (-> task2.complete()).should.throw "Dependent task 'wash dishes' is not completed."

If I run this command in terminal: mocha -r should --compilers coffee:coffee-script -R spec I have a failing test (the final one) saying that it was expecting an exception "Dependent task 'wash dishes' is not completed." but got 'undefined'.

If I change (-> task2.complete()).should.throw to -> task2.complete().should.throw by removing the parenthesis, the test passes, and fails if I don't throw the exception. But if I change the exception message to something random, it still passes. Am I doing something wrong? Shouldn't the test only pass if the message is literally "Dependent task 'wash dishes' is not completed."?


Source: (StackOverflow)

How do I reuse a test function with async calls in nodejs?

I'm new to node.js and it's been a while since I've worked with an asynchronous framework. In a procedural language such as python it's easy to have a list of inputs and expected outputs then to loop through them to test:

tests = {
  1: [2, 3],
  2: [3, 4],
  7: [8, 9],
}

for input, expected_out in tests.items():
  out = myfunc(input)
  assert(out == expected_out)

I'm attempting to do something similar with nodejs/mocha/should:

var should = require('should');

function myfunc(x, cb) { var y = x + 1; var z = x + 2; cb([y, z]); };

describe('.mymethod()', function() {
    this.timeout(10000);
    it('should return the correct output given input', function(done) {
        var testCases = {
                1: [2, 3],
                2: [3, 4],
                7: [8, 9],
            };

        for (input in testCases) {
            myfunc(input, function (out) {
                var ev = testCases[input];
                out.should.equal(ev);
            });
        }
    })
})

This results in:

  AssertionError: expected [ '11', '12' ] to be [ 2, 3 ]
  + expected - actual

   [
  +  2
  +  3
  -  "11"
  -  "12"
   ]

I have no idea where [ '11', '12' ] comes from, but it smacks of a thread safety issue.

Can anyone explain to me where these unexpected values are coming from?


Source: (StackOverflow)

How to extend 'should' library

I would like o introduce to should assert library, working for tests of my node.js app, my additional functions.

Something like in this pseudocode

should      = require "should"

myExists = (obj, msg) ->
  # my special exist logic

containSomething = (obj, msg) ->
  # my special assert logic

should.myExists = myExists
should.containSomething = containSomething


describe.only "`my extra `", ->
   it 'should be working', (done) ->
     obj = {}
     obj.should.myExists  
     obj.should.not.myExists  
     obj.should.containSomething {cool:obj}
     obj.should.not.containSomething {cool:obj}
     done()

Any suggestions how to do that in practice?


Source: (StackOverflow)

Using should.js how can I test for an empty object?

user1Stats.should.be.instanceof(Object);
(user1Stats).should.have.keys();

I get the following error:

Error: keys required
    at Object.Assertion.keys

The instanceof(Object) works, but I want to make sure there is no data in it.


Source: (StackOverflow)

How do I write a test for a binary download using mocha and should.js with sails.js?

I'm trying to write at test for a Sails.Js controller action that downloads a user's avatar image. The controller action looks like this:

/**
* Download avatar of the user with the specified id
*
* (GET /user/:id/avatar)
*/
avatar: function (req, res) {

  req.validate({
    id: 'string'
  });

  User.findOne(req.param('id')).exec(function (err, user){
        if (err) return res.negotiate(err);
        if (!user) return res.notFound();

        // User has no avatar image uploaded.
        // (should have never have hit this endpoint and used the default image)
        if (!user.avatarFd) {
          return res.notFound();
        }

        var SkipperDisk = require('skipper-disk');
        var fileAdapter = SkipperDisk(/* optional opts */);

        // Stream the file down
        fileAdapter.read(user.avatarFd)
        .on('error', function (err){
          return res.serverError(err);
        })
        .pipe(res);
    });
}

So far the test looks like this:

describe('try to download a user avatar', function() {
    var result;
    it('should return 200', function(done) {
        server
            .get('/user/' + testUser.id + '/avatar')
            .expect(200)
            .end(function(err, res) {
                if (err) return done(err);
                result = res.body;
                return done();
            });
        }
    }
    it('should return binary data stream', function(done) {
      // make some assertions.
    });
});

I want to add another test to make sure that what has been returned is binary data, but I can't figure out how this would be done. Anyone know the right way to go about this?

UPDATE

After attempting a solution in the mode that @sgress454 suggested below, I ended up with this test:

tmp = require('temporary'); 
  // https://github.com/vesln/temporary

// Write nonsense bytes to a file fixture.
var EOF = '\x04';
var size = 1000;
var fileFixture = new tmp.File();
fileFixture.writeFileSync(crypto.pseudoRandomBytes(size) + EOF);
fileFixture.size = size;

after(function() {
fileFixture.unlinkSync();
});

describe('try to download a user avatar', function() {
    var download;
    it('should return 200', function(done) {
        server
            .get('/user/' + testUser.id + '/avatar')
            .expect(200)
            .end(function(err, res) {
                if (err) return done(err);
                download = new Buffer(res.text, 'ascii');
                return done();
            });
        });
    it('should return binary stream', function(done) {
        var testAvatar = fs.readFileSync(fileFixture.path);
        download.toString('base64').should.be.equal(testAvatar.toString('base64'));
        done(); 
    });
});

So this test mocks up a file using temporary. The trouble is that when I compare the result I get back from the server and the mock file that I'm reading from the mocked file system, they aren't the same. I get the following as expected:

  +bEk277+9azo277+916jvv71g77+9KO+/vV/vv71577+977+9U8e9A++/ve+/vSgiF++/ve+/vWsi77+977+9BRRs77+977+977+9bO+/vSoGRW3vv73vv73dr++/ve+/vXEAIFbvv70p77+977+9WMuSSm/vv73vv71W77+977+9LULvv70J77+9eFfSoVsW77+977+9QAleLgDvv71T77+9de+/vRHvv71qyJPvv73vv73vv73vv73vv71S77+91L4sf++/vQHaiicDKXXvv71977+9NO+/vUzvv71YXe+/vTjvv70n77+9fWvvv73vv709YgoW77+9bmF/77+9JNK4LO+/vUNdNGjvv70TZMazS+2IjBdgL++/ve+/vRXvv71S77+977+9SHHvv70QY++/vSbvv70SC2US77+9eGnvv71cczVOFBp7fu+/ve+/ve+/ve+/vWTvv70B77+9cm/vv73vv73vv73vv70q77+977+9JSxY77+9TO+/vQbvv73vv71sREl+Qyrvv70JFXgSHBLvv71v77+977+9AkBPOwvvv73vv73vv71R77+9VSHvv71DZ2NB77+977+977+977+9Pu+/ve+/vcabMe+/ve+/ve+/ve+/vUFnXFJP77+977+977+977+9G1/vv73vv73vv71OQe+/ve+/vdmU77+9B++/vUts77+9Zu+/vS9uUH3vv73vv73vv71y77+9PlRXSSJ3UHHvv73vv71SBXvvv73vv70677+977+9dk5O77+9de+/vTzvv70Y77+9cmjvv73vv73vv73vv712UNC0WW7vv73vv71lZD4+77+9U++/vR4MNW8RY37vv70ZTUo2fl0sKu+/vUN/bipyPO+/vSrvv73vv73vv700Bjwa77+977+9RH8A77+977+977+9zrDvv73vv70JQ2tOKe+/vV7Mk2Hvv73vv73vv70L77+9Tu+/vQwPK++/ve+/ve+/vVTvv73vv70M77+977+9Zs2/Vu+/vXzvv73vv73vv71a77+977+977+9Au+/vSrvv73vv70S77+977+9eO+/ve+/vVFk77+977+9Jm4L77+977+9fVnRl05x77+9ai1SSDZiX2fvv73vv73vv73vv73vv73vv73vv73vv71Y77+977+977+9VFvvv71B77+9X++/vTbvv70w77+977+9TO+/vSQBMB4+77+977+9Z++/vTDvv73vv71/77+977+9Dnd9Be+/vUZCehYuFu+/vVfvv73vv73vv73vv73vv73vv70+HO+/ve+/ve+/ve+/ve+/vSgLVitLQO+/ve+/vUZP77+977+977+9adWy77+977+9H++/ve+/vWTvv71677+93Zzvv73vv73vv71t77+977+977+9BGMkIFkYSxRW77+977+977+9Ke+/vRoN77+9f9CIUXQXWu+/vSYp77+9VDPvv71fLAxU77+977+977+9N++/vTbvv73vv73vv71dIjzvv73vv73vv71Z77+977+9He+/ve+/vWd6LO+/vQDvv70Bae+/vRQZ77+977+90YLvv717Ji3vv716Bu+/ve+/ve+/vVpU77+9aO+/ve+/vWnvv73vv70u2a/vv73vv73vv71p77+9WiAh77+9JyLvv73vv73vv73vv71QIUzvv71pypRO77+9Fe+/vQ7vv70Z77+9Se+/vUHvv73vv73vv70tA++/vSjvv73vv73vv73vv716K8e677+977+977+977+9Zyjvv73vv71U77+9Oe+/vRcF77+9Ku+/ve+/ve+/ve+/vVl777+9ewUAUu+/ve+/ve+/vUV/GGA6fu+/ve+/vVfvv705BA50D++/vSrvv73vv73vv71d77+977+977+977+9KO+/ve+/vUBzbO+/ve+/ve+/ve+/vXUnPS7vv71gCe+/vQ/vv70d77+9P00d77+9Tx8cOz8ABe+/vRbvv70t77+9IO+/ve+/ve+/ve+/ve+/ve+/vSQt77+9GE7vv73vv73vv73vv73So++/vVTvv71BEgDvv73vv70BdRYeTO+/vTjvv71+Ku+/vXjTu++/ve+/ve+/vRQK77+9Su+/vTvskJB/b1dyU++/ve+/vW7vv71k77+9Pu+/ve+/ve+/ve+/ve+/vVk277+9Pyfvv73vv73vv70mXO+/ve+/ve+/ve+/ve+/vQIr77+9QO+/vS1nAyXvv73vv713Ve+/vVTvv70VcV5m77+9M++/ve+/ve+/vWUx77+9OT1g77+9MQnvv71N77+977+977+9byjvv73vv71W77+977+9x5rvv70PBO+/ve+/ve+/ve+/ve+/ve+/ve+/vQd0Ru+/ve+/vU1zG++/vW5W77+977+9ES9udy3vv71CbGpVDgXvv71977+977+9QhLvv71xfnEN77+9KzDvv70KKO+/vVDvv70E

And the following as the actual response:

  -bEk2/Ws6Nv3o/WD9KP1f/Xn9/VP9A/39KCIX/f1rIv39BRRs/f39bP0qBkVt/f1v/f1xACBW/Sn9/VjSSm/9/Vb9/S1C/Qn9eFehWxb9/UAJXi4A/VP9df0R/WoT/f39/f1S/T4sf/0BiicDKXX9ff00/Uz9WF39OP0n/X1r/f09YgoW/W5hf/0kuCz9Q100aP0TZLNLDBdgL/39Ff1S/f1Icf0QY/0m/RILZRL9eGn9XHM1ThQae379/f39ZP0B/XJv/f39/Sr9/SUsWP1M/Qb9/WxESX5DKv0JFXgSHBL9b/39AkBPOwv9/f1R/VUh/UNnY0H9/f39Pv39mzH9/f39QWdcUk/9/f39G1/9/f1OQf39VP0H/Uts/Wb9L25Qff39/XL9PlRXSSJ3UHH9/VIFe/39Ov39dk5O/XX9PP0Y/XJo/f39/XZQNFlu/f1lZD4+/VP9Hgw1bxFjfv0ZTUo2fl0sKv1Df24qcjz9Kv39/TQGPBr9/UR/AP39/bD9/QlDa04p/V4TYf39/Qv9Tv0MDyv9/f1U/f0M/f1mf1b9fP39/Vr9/f0C/Sr9/RL9/Xj9/VFk/f0mbgv9/X1ZV05x/WotUkg2Yl9n/f39/f39/f1Y/f39VFv9Qf1f/Tb9MP39TP0kATAePv39Z/0w/f1//f0Od30F/UZCehYuFv1X/f39/f39Phz9/f39/SgLVitLQP39Rk/9/f1pcv39H/39ZP16/Vz9/f1t/f39BGMkIFkYSxRW/f39Kf0aDf1/CFF0F1r9Jin9VDP9XywMVP39/Tf9Nv39/V0iPP39/Vn9/R39/Wd6LP0A/QFp/RQZ/f1C/XsmLf16Bv39/VpU/Wj9/Wn9/S5v/f39af1aICH9JyL9/f39UCFM/WmUTv0V/Q79Gf1J/UH9/f0tA/0o/f39/Xor+v39/f1nKP39VP05/RcF/Sr9/f39WXv9ewUAUv39/UV/GGA6fv39V/05BA50D/0q/f39Xf39/f0o/f1Ac2z9/f39dSc9Lv1gCf0P/R39P00d/U8fHDs/AAX9Fv0t/SD9/f39/f0kLf0YTv39/f2j/VT9QRIA/f0BdRYeTP04/X4q/Xj7/f39FAr9Sv07EH9vV3JT/f1u/WT9Pv39/f39WTb9Pyf9/f0mXP39/f39Aiv9QP0tZwMl/f13Vf1U/RVxXmb9M/39/WUx/Tk9YP0xCf1N/f39byj9/Vb9/dr9DwT9/f39/f39B3RG/f1Ncxv9blb9/REvbnct/UJsalUOBf19/f1CEv1xfnEN/Ssw/Qoo/VD9BA==

I'm not sure why the files would be different at this point. Perhaps the problem is in the way I'm parsing the data that comes back?


Source: (StackOverflow)

Should.js - determine equality between a single field in multiple object's against a single object

I'm testing an api with the wonderful Mocha and Should.js.

I do a GET and receive an array of objects, for example:

[{
  username: 'boris',
  something: 123
},
{ 
  username: 'jeremy',
  something: 456
},
{ 
  username: 'steven',
  something: 789
},
{ ... },
{ ... },
{ ... }]

For each object, I want to make sure that the username value matches a property in a different object:

mockUsernames = {
    a  : 'bill',
    b  : 'ben',
    c  : 'boris'
};

How can you achieve this? As an example I want something like this:

.get()
...

  var someData = res.body;

  someData.forEach(function (e){
    e.username.should.equal(mockUsernames.a || mockUsernames.b || mockUsernames.c);
  });

...

As expected this doesn't work as I want because should.equal uses equal comparison operator.

Any recommended should.js methods would be v.appreciated. I can't seem to find what I want, or maybe this should be approached differently.


Source: (StackOverflow)

Mocha async test handle errors

I'm trying to create a test case with Mocha but my code is asynchronous.

That's fine, I can add a "done" callback function to "it" and that will work perfectly fine for positive cases. But when trying to test negative cases, it will just make the test fail.

I would like to make something like this but asynchronous:

someObject.someMethod(null).should.equal(false)

Instead I can only test for a callback to return, instead of testing what really happend (null is not valid):

it('this should return false or an error', function(done) {
    someObject.someMethod(null, '', done);
});

I would like to write something like this:

it('this should return false or an error', function(done) {
    someObject.someMethod(null, '', done).should.throw();
});

but that would lead to this error:

"TypeError: Cannot read property 'should' of undefined"

I also tried using expect and assert, but the same rules apply.

Any clues? Thanks

EDIT #1:

I've unsuccessfully tried:

Using true/false

return (true); // ok
retur (false); // error

Using callback:

callback(); // ok
callback(err); // error

Using callback2:

callback(true); // ok
callback(false); // error

Using callback3:

callback(null); // ok
callback(new Error()); // error

Using throw (also inside a try/catch block):

// a
 throw new Error();
callback();  

// b
 throw new Error();
callback(new Error());  

// c
 throw new Error();
callback(false);  

I have also tried several combinations such as returning and calling a callback, returning on success but throwing or calling a callback on error and conversely..

EDIT #2:

it('should throw', function(done) {
  (function(done) {
    someObject.someMethod(null, '', done)
  }).should.throw();
});`

EDIT #3:

To wrap up on the test-side:

it('this should return false or an error', function(done) {
    someObject.someMethod(null, function(err, value) {
        expect(value === false || err instanceof Error).toEqual(true);
       return done();
    });
}); 

And on the code-side: function(var, callback)

...
callback(new Error('your comments'), false);
// or
callback(new Error('your comments'));
...
// if successful:
callback();
// or
callback(null);
// or
callback(null, 'foo');

Source: (StackOverflow)

Node mocha array should contain an element

I want to do a simple assertion of something like

knownArray.should.include('known value')

The array is correct, but I simply can't figure out the proper assertion to use to check whether the array has this value (the index doesn't matter). I also tried should.contain but both of these throw an error that Object #<Assertion> has no method 'contain' (or 'include')

How can I check that an array contains an element using should?


Source: (StackOverflow)

callback being called twice when my unit test fails

I can't figure out why my save callback is being called twice in my mocha test when the callback fails. It doesn't call the save twice, it only fires the callback for the save again but with the 'should' error when my 2nd unit test fails. If I take out the failing 'should' assertion should.exist err from the second test it seems to work fine and doesn't trigger the save index callback twice.

class User

  constructor : (@name, @email, @pwd) ->
  save : (callback) ->
    unless this.validate()
      throw new Error('invalid data')
    else
      user = 
        name  : @name
        email : @email
        pwd   : @pwd

      node = db.createNode user

      node.save (err) ->
        unless err        
          user.id = node.id;
          node.index 'User', 'name', user.name.toLowerCase(), (err2) ->
            #why is this being fired twice when an assert in the callback fail?
            console.log '----------- triggering the save callback'
            callback err2, user

        else
          callback err

the mocha test

describe "User", ->
    it "should be able to save", (done) ->
        user = new User("quark", "quark@ds9.com", "profit")
        user.save (err, result) ->
            should.exist result
            done err

    #this second unit test should fail since the duplicate checking is not yet implemented
    it "should not allow duplicates to be saved", (done) ->
        user = new User("quark", "quark@ds9.com", "profit")
        user.save (err, result) ->
            console.log err
            should.exist err #this triggers the user.save callback to be fired twice
            done null

And the test results

  User
    ◦ should be able to save: ----------- triggering the save callback
    ✓ should be able to save (43ms)
    ◦ should not allow duplicates to be saved: ----------- triggering the save callback
undefined
----------- triggering the save callback
{ name: 'AssertionError',
  message: 'expected undefined to exist',
  actual: undefined,
  expected: undefined,
  operator: undefined }
    ✓ should not allow duplicates to be saved 


  ✔ 2 tests complete (69ms)

Source: (StackOverflow)

Testing Errors passed back with Callbacks with mocha and should

UPDATE 2-July-2013

Using the last approach with the wrapped anonymous function can introduce some strange testing behavior. If you expect a thrown error, but there is an error in the actual execution the test will pass, but will pass on any error and probably not the one you were expecting. I do two things, if its an error i am specifying i ensure the error text returned from the stub and the thrown error are the same. If it is from a third party library where i don't necessarily know the errors i will put some arbitrary value so that i know the passes are specific to the units i am testing. Example using sinon.js to stub some shizzle.

    it('should return an error if the save fails', function(){
        stubCall.restore();
        stubCall = sinon.stub(Provider, 'save').callsArgWith(1, new Error('Save Error'));

        (function(){
            User.create(fakeUser, function(err, user){
               if(err)
                throw err;
            });
        }).should.throw("Save Error");
    });

I am getting into Node.js and trying to do some Behaviour Driven Development(BDD) with Mocha and should.js (and sinon in there as well at some point).

One thing i am having problems with is testing errors returned by a call back, for instance this simple test:

it('should return an error if you try and execute an invalid Query object', function () {
        var stubQuery = {}; 

        Provider.execute(stubQuery, function (err) {
            //should.not.exist(err);
            should.have.property('message', 'Invalid Query Object');
        });
    });

with the function:

PostgresqlProvider.prototype.execute = function (query, cb) {

};

It doesn't matter what i try and test, the test always passes (should.exist, etc), and the only way i can get it to fail first is by adding cb(null); into the execute function, which kinda goes against what i am doing as i am trying to test before adding behaviour, not adding behaviour to fail a test.

I know i am doing some real newb mistake here, probably on a few levels but i am not grasping the testing of an error passed as a call back with is not thrown (which i am sure i could test easier)!

UPDATE

Using the code from Herman, i adjusted and that indeed words (the test is failing with no behavior defined)

        it('should return an error if you try and execute an invalid Query object', function () {
        var stubQuery = {};
        Provider.execute(stubQuery, function (err) {
            if (err) throw new Error(err);
        }).should.throw();
    });

issue now is i can't "catch" the error if sent in the callback to pass the test, the should.throw method doesn't get called, it just states that expected a throw to happen but didnt even though i am returning an error to the callback from my method. This could be down to scope but i am unsure if i should add some form of closure, and at what level.

UPDATE 2

Figured it out, i needed to wrap the call to the function inside a closure, not the callback (Doh!) and then place the assert (should.throw) at the end of the closure;

        it('should return an error if you try and execute an invalid Query object', function () {
        var stubQuery = {};
        (function(){
            Provider.execute(stubQuery, function (err) {     
                if (err) 
                    throw err;
            });
         }).should.throw();
    });

Source: (StackOverflow)

Forcing Mongodb errors for unit testing in NodeJS

I'm writing my first tests for a Mongodb database using should.js, and need a way to force errors in various functions that make database calls.

I've spent a little time exploring how Rewire.js might help, but am still new enough to Mongo that I'm not sure what I should 'rewire' to force database errors.

Perhaps there is a better way to write the functions to trigger errors during testing.

I appreciate any ideas.


For what it's worth, this is what I've come up with and would appreciate any comments. I didn't have long to write this up, so please forgive any typos.

The typical layout of a function with an embedded async call is usually something like:

function my_function(callback) {
    async_call(function(err, doc) {
        if (err) {
            //Do error prep such as with VError
            callback(err, null);
        } else {
            //Do success prep such as:
            var result = doc.property;
            callback(null, result);
        }
    });
}

The problem is having a great way to test the code in the error path. There are solutions like Rewire which do well if, by changing the value of a global variable you can trigger the desired error, but its hard to find a way to break Mongodb calls by rewriting a global.

My solution was to: 1) rewrite my async functions that I need to "break" in order to test

my_function = {
    get: function(callback) {
        async_call(function(err, doc) {
            my_function.manage_return(err, doc, callback);
        });
    },
    manage_return: function(err, doc, callback) {         
        if (err) {
            //Do error prep such as with VError
            callback(err, null);
        } else {
            //Do success prep such as:
            var result = doc.property;
            callback(null, result);
        }
    });
}

2) During testing, if I need to force an error, I just rewrite get:

var original_get = my_lib.my_function.get; //NO parenthesis!!!
my_lib.my_function.get = function(callback) {
    my_lib.my_function.manage_return("This is a forced error", null, callback);
};

Later if I need to restore the function:

my_lib.my_function.get = original_get;

I've actually written a constructor that makes the rewrite/restore procedure much more streamlined, that I'd be glad to post if anyone is interested.

I did try using Rewire to handle the rewrite/restore procedure without success. Worse, "rewritten" code can't be single-stepped.

PROS
*Doesn't use eval
*Single step debugging (at least in WebStorm) works
*Can force any error at will
*Doesn't alter the function signature
*Gives ability to force a specific function to fail, which is a huge help when testing error handling of larger functions that rely on several subordinate functions

CONS
*I have to rewrite all my async functions as objects with get and mange_return
*If the function is in a module, I have to export the function in order to rewrite/restore it

Thoughts?


Source: (StackOverflow)

Use of should.js with Coffeescript

I want to use should.js together with mocha in a Node.js projects which I write in Coffeescript.

In pure Javascript a expression in should.js is like

(function(){
  throw new Error('fail');
}).should.throw();

Now I want to write the same expression in Coffeescript. Something like

object.function().should.throw

But that compiles to

object["function"]().should["throw"];

Where is my mistake in my Coffescript code?


Source: (StackOverflow)

Drop MongoDB database before running Mocha test

If I try to drop the database using after (at the end of my tests) it works.

If I try the following:

var db = mongoose.connect('mongodb://localhost/db-test')

describe('Database', function() {

    before(function (done) {
        db.connection.db.dropDatabase(function(){
            done()
        })
    })

    ...

it does not drop the DB. what is going on? I would prefer dropping the db before starting testing -- so that after testing I can explore the db.


Source: (StackOverflow)