Jest: toThrowError not working with custom errors and Babel

Created on 17 Nov 2016  ·  5Comments  ·  Source: facebook/jest

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
If you try to test whether or not a function is throwing an error of a specific type with toThrowError, and are using Babel/ES6 classes, then the error matching is failing to recognize that the types are the same.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal repository on GitHub that we can npm install and npm test.
If you are using Babel and Jest, and try to run Jest against the following test:

class MyError extends Error {}

function foobar () {
  throw new MyError();
}

it('should recognize the error and pass', () => {
  expect(() => {
    foobar();
  }).toThrowError(MyError);
});

this will result in a failure similar to the following (line numbers won't be perfect, since I cleaned up the code a little):

expect(function).toThrowError(type)

    Expected the function to throw an error of type:
      "MyError"
    Instead, it threw:
      Error
        at MyError.Error (native)
          at new MyError (src/models/__tests__/my-test.js:13:1363)
          at foobar (src/models/__tests__/my-test.js:13:1437)
          at src/models/__tests__/my-test.js:18:7
          at Object.<anonymous> (src/models/__tests__/my-test.js:19:8)
          at process._tickCallback (internal/process/next_tick.js:103:7)

      at Object.<anonymous> (src/models/__tests__/my-test.js:19:8)
      at process._tickCallback (internal/process/next_tick.js:103:7)

What is the expected behavior?
I would expect the above test to pass, since the method is clearly throwing the type of error that was given to the toThrowError method.

Run Jest again with --debug and provide the full configuration it prints. Please mention your node and npm version and operating system.
Node Version: v6.3.1
NPM Version: v3.10.3

Debug Output:

jest version = 17.0.2
test framework = jasmine2
config = {
  "rootDir": "/Users/justin/code/work/generator-test",
  "name": "-Users-justin-code-work-generator-test",
  "setupFiles": [
    "/Users/justin/code/work/generator-test/node_modules/babel-polyfill/lib/index.js"
  ],
  "testRunner": "/Users/justin/code/work/generator-test/node_modules/jest-jasmine2/build/index.js",
  "transform": [
    [
      "^.+\\.jsx?$",
      "/Users/justin/code/work/generator-test/node_modules/babel-jest/build/index.js"
    ]
  ],
  "usesBabelJest": true,
  "automock": false,
  "bail": false,
  "browser": false,
  "cacheDirectory": "/var/folders/9d/pytzv6654jgd3q__9m1d8z3r0000gn/T/jest",
  "coveragePathIgnorePatterns": [
    "/node_modules/"
  ],
  "coverageReporters": [
    "json",
    "text",
    "lcov",
    "clover"
  ],
  "expand": false,
  "globals": {},
  "haste": {
    "providesModuleNodeModules": []
  },
  "mocksPattern": "__mocks__",
  "moduleDirectories": [
    "node_modules"
  ],
  "moduleFileExtensions": [
    "js",
    "json",
    "jsx",
    "node"
  ],
  "moduleNameMapper": {},
  "modulePathIgnorePatterns": [],
  "noStackTrace": false,
  "notify": false,
  "preset": null,
  "resetMocks": false,
  "resetModules": false,
  "snapshotSerializers": [],
  "testEnvironment": "jest-environment-jsdom",
  "testPathDirs": [
    "/Users/justin/code/work/generator-test"
  ],
  "testPathIgnorePatterns": [
    "/node_modules/"
  ],
  "testRegex": "(/__tests__/.*|\\.(test|spec))\\.jsx?$",
  "testURL": "about:blank",
  "timers": "real",
  "transformIgnorePatterns": [
    "/node_modules/"
  ],
  "useStderr": false,
  "verbose": null,
  "watch": false,
  "cache": true,
  "watchman": true
}
 FAIL  src/models/__tests__/user-test.js
  ● should recognize the error and pass

    expect(function).toThrowError(type)

    Expected the function to throw an error of type:
      "MyError"
    Instead, it threw:
      Error
        at MyError.Error (native)
          at new MyError (src/models/__tests__/user-test.js:13:1363)
          at foobar (src/models/__tests__/user-test.js:13:1437)
          at src/models/__tests__/user-test.js:18:7
          at Object.<anonymous> (src/models/__tests__/user-test.js:19:8)

      at Object.<anonymous> (src/models/__tests__/user-test.js:19:8)

    ✕ should recognize the error and pass (6ms)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 0 passed, 1 total
Snapshots:   0 total
Time:        1.054s
Ran all test suites.

Most helpful comment

This is something that babel doesn't cover: https://babeljs.io/docs/usage/caveats/#classes

For a reference, here is more information about why this occurs.

All 5 comments

I should also note that if you replace the MyError class with the following, the same test passes:

function MyError() {}

MyError.prototype = Object.create(Error.prototype);

This is something that babel doesn't cover: https://babeljs.io/docs/usage/caveats/#classes

For a reference, here is more information about why this occurs.

Ah, I wasn't aware of that. I'll go ahead and close this issue.

Thanks for the timely response!

I have having the same issue but with typescript. This issue was fixed on jasmine by using intanceof.
https://github.com/jasmine/jasmine/issues/819
https://github.com/jasmine/jasmine/commit/ff029b37b5b2fb95c6f2252713b14586f86786cb

Is this applicable in this case?

Was this page helpful?
0 / 5 - 0 ratings