tj / should.js

BDD style assertions for node.js -- test framework agnostic
MIT License
2.75k stars 195 forks source link

Should causes async Mocha tests to timeout #71

Closed tgvashworth closed 11 years ago

tgvashworth commented 12 years ago

I'm running Mocha in watch mode, compiling CoffeeScript tests.

# This fails by timing out
it 'should be able to grab qba6sms/published from Typekit', (done) ->
    $.getJSON 'http://typekit.com/api/v1/json/kits/qba6sms/published?callback=?', (data, txt, xhr) ->
      data.should.be.ok
      done()
# This does not fail
it 'should be able to grab qba6sms/published from Typekit', (done) ->
    $.getJSON 'http://typekit.com/api/v1/json/kits/qba6sms/published?callback=?', (data, txt, xhr) ->
      assert.ok data
      done()

I'm not sure what's up – am I doing something wrong, or is it a bug?

tj commented 12 years ago

what's the compiled code? maybe CS is fucking it up

tgvashworth commented 12 years ago

Could it be the returns?

return it('should be able to grab things from Typekit', function(done) {
  return $.getJSON('http://typekit.com/api/v1/json/kits/qba6sms/published?callback=?', function(data, txt, xhr) {
    data.should.be.ok;
    return done();
  });
});
tj commented 12 years ago

they shouldn't matter

tgvashworth commented 12 years ago

Didn't think so, any other ideas? Mocha's compiling it on the fly... I might try compiling it with coffee and running the tests on that code.

tgvashworth commented 12 years ago

Just tried chai – expect(data) works great, but should times out.

tgvashworth commented 12 years ago
describe 'typekit', () ->
  it 'should be able to fetch the example kit', (done) ->
    this.timeout 8 * 1000
    typekit.get 'http://typekit.com/api/v1/json/kits/qba6sms/published?callback=?', (data) ->
      data.kit.id.should.equal 'qba6sms'
      done()
  it 'should be able to fetch my kits', (done) ->
    this.timeout 8 * 1000
    typekit.get 'http://typekit.com/api/v1/json/kits?token=xxxxx&callback=?', (data) ->
      data.should.be.a 'object'
      done()

Top works, bottom times out. When I add data.should.be.a 'object' to the top, it times out. This ain't the CS – exact same problem with raw JS tests.

tj commented 12 years ago

some browsers don't really properly expose uncaught exceptions that's probably why it's timing out

tgvashworth commented 12 years ago

I'm using Mocha in watch mode (although it fails in normal mode too):

@./node_modules/.bin/mocha -w -R min -r should --compilers coffee:coffee-script
tj commented 12 years ago

oh i see this is with node, i'll look into it soon

tgvashworth commented 12 years ago

Thanks.

Some more info, for that last bit of code: First example: typeof data.kit.id.should is object Second example: typeof data.should is undefined

In both cases data is an object.

enyo commented 11 years ago

Having the exact same problem. Tests timeout with should. Using the latest versions of node, mocha and should.

enyo commented 11 years ago

I have now tested it with chai and without should and experienced the same problem... So it seems to be more related to mocha than should.

wprater commented 10 years ago

Having the same issue, where a failed should assertion causes mocha test to time out and never call done. This happens within a return mongoose promise.

btd commented 10 years ago

Show me your code.

wprater commented 10 years ago

model

schema.statics.ignite = function (foo) {
  var prom = new mongoose.Promise();
  setTimeout(function () {
    prom.resolve(null, 'foobar');
  } , 500);
  return prom;
};

test

  it('failing test in resolved promise times out', function (done) {
    Model.ignite('foo')
    .then(function (flare) {
      true.should.be.false;
      done();
    }, done);
  });
btd commented 10 years ago

Not sure about mongosee promises, but q.js require to add to final promise .done() or return it. Maybe the same with mongoose promises? In should there is nothing to block.

wprater commented 10 years ago

Ahh, thanks @btd , I needed to add the #end to finalized the chain. But there is not chain ;) I thought you only needed to call end if you were chaining then's.

it('failing test in resolved promise times out', function (done) {
    Model.ignite('foo')
    .then(function (flare) {
      true.should.be.false;
      done();
    }, done)
    .end();
  });
nicohvi commented 10 years ago

+1

leftstick commented 8 years ago

The thing you are encountering is nothing to do with mocha, should or even chai. It caused by promise.

When the should fails, Promise turn the process into reject state, instead throw the error directly.

Just modify your code as following:

it('promise', function(done) {
        new Promise(function(resolve, inject){
            setTimeout(function(){
                resolve(false);
            }, 20);
        })
            .then(function(state) {
                state.should.be.ok;
                done();
            })
            .catch(done);
    });

You have to catch the error yourself