From f22021544e10aac2fab74a6ed3cf7cd366728d45 Mon Sep 17 00:00:00 2001 From: Solaman Huq Date: Tue, 14 Nov 2023 14:20:15 -0800 Subject: [PATCH 1/3] add helper method to observe errors --- src/test.js | 25 +++++++++++++++++++++++++ test/unit-test-example.js | 11 +++++++++++ 2 files changed, 36 insertions(+) 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..61656e3 100644 --- a/test/unit-test-example.js +++ b/test/unit-test-example.js @@ -9,6 +9,17 @@ class ExampleTest extends BaseTest { testInvalidCall () { expect(() => Example.broken()).toThrow() } + + async testCatchError () { + const shouldThrow = () => { + throw new Error('hello!') + } + const error = await this.catchError(shouldThrow) + expect(error.message).toEqual('hello!') + const doesNotThrow = () => 2 + await expect(this.catchError(doesNotThrow)) + .rejects.toThrow() + } } runTests(ExampleTest) From 30a1ab12cf1fcf74b5373972abc5ac35e0404d06 Mon Sep 17 00:00:00 2001 From: Solaman Huq Date: Tue, 14 Nov 2023 14:58:49 -0800 Subject: [PATCH 2/3] update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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": { From ee37868c915eae6466b85a509adb1dfafe110a5b Mon Sep 17 00:00:00 2001 From: Solaman Huq Date: Tue, 14 Nov 2023 15:26:17 -0800 Subject: [PATCH 3/3] CRC: test utility of method more closely --- test/unit-test-example.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/test/unit-test-example.js b/test/unit-test-example.js index 61656e3..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) @@ -12,10 +19,18 @@ class ExampleTest extends BaseTest { async testCatchError () { const shouldThrow = () => { - throw new Error('hello!') + 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()