From 7cff87f3f664f3d411cf47ba2494f458fd54a6d5 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Mon, 16 Oct 2023 16:08:25 +0000 Subject: [PATCH 1/2] fix: upgrade @types/sinon from 10.0.16 to 10.0.17 Snyk has created this PR to upgrade @types/sinon from 10.0.16 to 10.0.17. See this package in npm: https://www.npmjs.com/package/@types/sinon See this project in Snyk: https://app.snyk.io/org/jlenon7/project/97097eb1-6953-4d11-a9f3-958b2ecba250?utm_source=github&utm_medium=referral&page=upgrade-pr --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4751619..b8dd443 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@japa/run-failed-tests": "^1.1.0", "@japa/runner": "^2.2.2", "@japa/spec-reporter": "^1.3.3", - "@types/sinon": "^10.0.16", + "@types/sinon": "^10.0.17", "c8": "^8.0.1", "sinon": "^15.1.0" }, @@ -1186,9 +1186,9 @@ "dev": true }, "node_modules/@types/sinon": { - "version": "10.0.16", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.16.tgz", - "integrity": "sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ==", + "version": "10.0.17", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.17.tgz", + "integrity": "sha512-+6ILpcixQ0Ma3dHMTLv4rSycbDXkDljgKL+E0nI2RUxxhYTFyPSjt6RVMxh7jUshvyVcBvicb0Ktj+lAJcjgeA==", "dependencies": { "@types/sinonjs__fake-timers": "*" } diff --git a/package.json b/package.json index e175d6b..09ff743 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@japa/run-failed-tests": "^1.1.0", "@japa/runner": "^2.2.2", "@japa/spec-reporter": "^1.3.3", - "@types/sinon": "^10.0.16", + "@types/sinon": "^10.0.17", "c8": "^8.0.1", "sinon": "^15.1.0" }, From fb9502c17230b4326c1cdd25a7624453030dd701 Mon Sep 17 00:00:00 2001 From: jlenon7 Date: Wed, 18 Oct 2023 16:33:51 +0100 Subject: [PATCH 2/2] feat(mock): mock props and restore single mock --- package-lock.json | 4 +-- package.json | 2 +- src/mocks/Mock.ts | 21 ++++++++++++++++ src/mocks/MockBuilder.ts | 20 +++++++++++++++ tests/unit/mocks/MockTest.ts | 49 ++++++++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4751619..d1a97b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@athenna/test", - "version": "4.12.0", + "version": "4.13.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@athenna/test", - "version": "4.12.0", + "version": "4.13.0", "license": "MIT", "dependencies": { "@japa/assert": "^1.4.1", diff --git a/package.json b/package.json index e175d6b..e179cce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@athenna/test", - "version": "4.12.0", + "version": "4.13.0", "description": "The Athenna test runner. Built on top of Japa.", "license": "MIT", "author": "João Lenon ", diff --git a/src/mocks/Mock.ts b/src/mocks/Mock.ts index 0308c66..6ca1c5c 100644 --- a/src/mocks/Mock.ts +++ b/src/mocks/Mock.ts @@ -82,6 +82,27 @@ export class Mock { return Mock.sandbox.match(value) } + /** + * Restore a mock to default behavior. + * + * @example + * ```ts + * Mock.when(console, 'log').return(undefined) + * + * Mock.restore(console.log) + * ``` + */ + public static restore(value: any): void { + if (!value.restore) { + return + } + + value.restore() + value.resetHistory() + value.resetBehavior() + value.reset() + } + /** * Restore all mocks to default. */ diff --git a/src/mocks/MockBuilder.ts b/src/mocks/MockBuilder.ts index 0062801..636b7f8 100644 --- a/src/mocks/MockBuilder.ts +++ b/src/mocks/MockBuilder.ts @@ -18,6 +18,26 @@ export class MockBuilder { private sandbox: SinonSandbox ) {} + /** + * Mock a property changing it value. + * + * @example + * ```ts + * import { Mock } from '@athenna/test' + * + * const mock = Mock.when(console, 'log').value(() => {}) + * + * mock.called // false + * ``` + */ + public value(value: T): Stub { + const stub = this.sandbox.stub(this.object, this.method) + + stub.value(value) + + return stub + } + /** * Mock the method to return the given value. * diff --git a/tests/unit/mocks/MockTest.ts b/tests/unit/mocks/MockTest.ts index 84aaa6e..a918369 100644 --- a/tests/unit/mocks/MockTest.ts +++ b/tests/unit/mocks/MockTest.ts @@ -52,6 +52,17 @@ export default class MockTest { assert.calledWith(spy, 1) } + @Test() + public async shouldBeAbleToMockObjectPropertyWithDifferentValues({ assert }: Context) { + const userService = new UserService() + + Mock.when(userService, 'findById').value(() => ({ id: 2 })) + + const value = userService.findById(1) + + assert.deepEqual(value, { id: 2 }) + } + @Test() public async shouldBeAbleToMockObjectMethodsToReturnValue({ assert }: Context) { const userService = new UserService() @@ -121,4 +132,42 @@ export default class MockTest { await assert.doesNotRejects(() => userService.find()) await assert.doesNotRejects(() => userService.findById(1)) } + + @Test() + public async shouldBeAbleToRestoreASingleMockedMethod({ assert }: Context) { + const userService = new UserService() + + Mock.when(userService, 'find').reject(new Error('ERROR_MOCK')) + Mock.when(userService, 'findById').reject(new Error('ERROR_MOCK')) + + await assert.rejects(() => userService.find(), Error) + await assert.rejects(() => userService.findById(1), Error) + + Mock.restore(userService.find) + Mock.restore(userService.findById) + + await assert.doesNotRejects(() => userService.find()) + await assert.doesNotRejects(() => userService.findById(1)) + } + + @Test() + public async shouldBeAbleToRestoreASingleMockedProperty({ assert }: Context) { + const userService = new UserService() + + const mockFind = Mock.when(userService, 'find').value(() => { + throw new Error('ERROR_MOCK') + }) + const mockFindById = Mock.when(userService, 'findById').value(() => { + throw new Error('ERROR_MOCK') + }) + + await assert.rejects(() => userService.find(), Error) + await assert.rejects(() => userService.findById(1), Error) + + Mock.restore(mockFind) + Mock.restore(mockFindById) + + await assert.doesNotRejects(() => userService.find()) + await assert.doesNotRejects(() => userService.findById(1)) + } }