diff --git a/package.json b/package.json index 8b9f7fb..76d1651 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@pocketgems/unit-test", - "version": "0.1.1", + "version": "0.2.0", "description": "A thin wrapper around Jest and Supertest to provide better organization", "main": "src/test.js", "scripts": { diff --git a/src/test.js b/src/test.js index 1ab7558..d762dcc 100644 --- a/src/test.js +++ b/src/test.js @@ -2,6 +2,12 @@ if (Number(process.env.INDEBUGGER)) { jest.setTimeout(30 * 60 * 1000) } +/** + * Helper error when attempting to examine contents of a given error. + * Should be used in conjunction with BaseServiceTest.prototype.getError + */ +class NoErrorThrownError extends Error {} + class BaseTest { _listTestsOn (obj) { return Object.getOwnPropertyNames(obj).filter(name => { @@ -41,6 +47,25 @@ class BaseTest { async beforeEach () {} async afterEach () {} + /** + * Catches error from specified call. Error may be examined by calling + * tests. + * This approach is recommended for in-depth assertions on errors: + * https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/no-conditional-expect.md#how-to-catch-a-thrown-error-for-testing-without-violating-this-rule + * @param {Promise} call - function expected to throw + * @throws {NoErrorThrownError} - exception if 'call' method + * does not throw. + * @returns {Error} error thrown be inner call method. + */ + async catchError (call) { + try { + await call() + } catch (error) { + return error + } + throw new NoErrorThrownError() + } + runTests () { describe(this.constructor.name, () => { beforeAll(async () => { diff --git a/test/unit-test-example.js b/test/unit-test-example.js index 2686440..5958a9f 100644 --- a/test/unit-test-example.js +++ b/test/unit-test-example.js @@ -1,6 +1,13 @@ const { Example } = require('../example/feature') const { BaseTest, runTests } = require('../src/test') +class CustomError extends Error { + constructor(message, customData) { + super(message) + this.customData = customData + } +} + class ExampleTest extends BaseTest { testMultiply () { expect(Example.multiply(2, 3)).toBe(6) @@ -9,6 +16,25 @@ class ExampleTest extends BaseTest { testInvalidCall () { expect(() => Example.broken()).toThrow() } + + async testCatchError () { + const shouldThrow = () => { + throw new CustomError('hello!', { + a: 33, + b: [1,2] + }) + } + const error = await this.catchError(shouldThrow) + expect(error).toBeInstanceOf(CustomError) + expect(error.message).toEqual('hello!') + expect(error.customData).toEqual({ + a: 33, + b: [1,2] + }) + const doesNotThrow = () => 2 + await expect(this.catchError(doesNotThrow)) + .rejects.toThrow() + } } runTests(ExampleTest)