New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expect().toBe() crashes silently when failing called from an async callback #3519

Closed
mo opened this Issue May 8, 2017 · 2 comments

Comments

Projects
None yet
3 participants
@mo
Copy link
Contributor

mo commented May 8, 2017

using jest 20.0.0, the following test crashes silently on the expect().toBe() and thus fails to call done() so it ends up hitting the jasmine default timeout. If you put a try/catch around the expect().toBe() line you can see that the error it crashes on (and fails to print) is that it cannot compare undefined to "hello" because they have different types. Also note that if you uncomment line 6 and comment out the setTimeout() line, effectively converting the asynchronous callback into a synchronous callback; then jest correctly prints the error immediately and doesn't hit the timeout. I'm expecting jest to properly report the error, even for the asynchronous callback case.

const isCurrentlyBuggy = true;

function sometimesBuggyFunc(callback) {
  if (isCurrentlyBuggy) {
    // If callback is invoked synchronously jest correctly reports: undefined != 'foo'
    //callback(undefined);

    // If callback if invoked asynchronously jest crashes silently on the
    // expect().toBe() and thus never calls done() causing the test case
    // to hang until jasmine default timeout is reached.
    setTimeout(() => callback(undefined), 0);
  } else {
    callback('hello');
  }
}

test.only('the thing', done => {
  expect.assertions(1);
  sometimesBuggyFunc(actual => {
    expect(actual).toBe('foo');
    done();
  });
});
@thymikee

This comment has been minimized.

Copy link
Collaborator

thymikee commented May 10, 2017

You need to catch the error and call done.fail(). This is how it works :(
However this is not an issue, if you're returning a promise from test.
See docs on that: http://facebook.github.io/jest/docs/en/asynchronous.html#promises

@thymikee thymikee closed this May 10, 2017

@randycoulman

This comment has been minimized.

Copy link

randycoulman commented Jun 16, 2017

@mo I just ran into this as well. I ended up making myself a little helper function:

function makeCallback(done, body) {
  return (...args) => {
    try {
      body(...args);
      done();
    } catch (error) {
      done.fail(error);
    }
  };
}

Using this, you'd replace your code above with:

sometimesBuggyFunc(makeCallback(done, actual => {
  expect(actual).toBe('foo');
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment