2
votes

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');
2
How are you throwing the error?Rodrigo Medeiros
I edited the question to answer this, but I have tried several combination of throw, error, return...nico

2 Answers

1
votes

Assuming that someObject.someMethod adheres to the regular Node.js callback convention (error as first argument, value as second), you could use something like this:

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

I inferred from the name of the test case that you want to test for two situations: either the method is "returning" an error, or it's "returning" a value of false (by calling the callback function with the appropriate arguments).

0
votes

You could wrap done in a anonymous function, and process (err,res) manually and call done with hard coded inputs. Or:

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