{"id":17604616,"url":"https://github.com/matthewmcnew/safe-mock","last_synced_at":"2025-04-30T10:11:11.862Z","repository":{"id":48440233,"uuid":"79077271","full_name":"matthewmcnew/safe-mock","owner":"matthewmcnew","description":"Statically Typed: TypeScript Mocks","archived":false,"fork":false,"pushed_at":"2021-07-26T11:14:06.000Z","size":98,"stargazers_count":5,"open_issues_count":19,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-30T15:07:14.189Z","etag":null,"topics":["mocks","stub","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/matthewmcnew.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-16T02:56:18.000Z","updated_at":"2023-09-17T08:01:15.000Z","dependencies_parsed_at":"2022-07-28T23:09:32.551Z","dependency_job_id":null,"html_url":"https://github.com/matthewmcnew/safe-mock","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewmcnew%2Fsafe-mock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewmcnew%2Fsafe-mock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewmcnew%2Fsafe-mock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewmcnew%2Fsafe-mock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matthewmcnew","download_url":"https://codeload.github.com/matthewmcnew/safe-mock/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251683355,"owners_count":21626953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mocks","stub","typescript"],"created_at":"2024-10-22T14:10:15.983Z","updated_at":"2025-04-30T10:11:11.843Z","avatar_url":"https://github.com/matthewmcnew.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Safe Mock\n\n[![Build Status](https://travis-ci.org/matthewmcnew/safe-mock.svg?branch=master)](https://travis-ci.org/matthewmcnew/safe-mock)\n[![Chat](https://img.shields.io/badge/help-gitter-eb9348.svg?style=flat)](https://gitter.im/Safe-Mock)\n\nSafe Mock is a library for Typescript (or Javascript) that allows mocks to be created from typescript interfaces or classes and utilized with simple typesafe syntax.\n\nThe syntax is inspired by Mockito.\n\nCheck out the examples below to get started:\n\n### Quick Start\n\n```bash\nnpm install safe-mock\n```\n\nThen import it in your tests:\n\n```typescript\nimport SafeMock, {when, verify} from \"safe-mock\";\n\n```\n\nCreate your first Safe Mock like this:\n\n```typescript\ninterface SomeService {\n    generate(key: string): string;\n}\n\nconst mockSomeService = SafeMock.build\u003cSomeService\u003e();\n\n```\n\nConfigure the mock to return values using SafeMock's `when`\n\n```typescript\nwhen(mockSomeService.mockSomeService(\"key\")).return(\"generatedKey\");\nwhen(mockSomeService.mockSomeService(\"other\")).return(\"otherGeneratedKey\");\n\n```\n\nAssert that mocks were used correctly with SafeMock's `verify`\n\n```typescript\nverify(mock.mockSomeService).calledWith(\"key\");\n```\n### Gotchas\n* SafeMock requires TypeScript 2.1 or later.\n* SafeMock requires a Javascript runtime with support for the [proxy object](http://caniuse.com/#feat=proxy).\n* If running on Node.js version 6+ is required.\n\n## The Details\n### Creating mocks\n\nMocks can be created from an interface, class, or functions.\n\n##### Creating mocks of interfaces\n```typescript\nimport SafeMock, {Mock} from \"safe-mock\";\n\ninterface SomeService {\n    createSomething(argument: number): string;\n}\n\n// mock an interface by passing the type of the mock as a generic to the build method  \nconst mock: Mock\u003cSomeService\u003e = SafeMock.build\u003cSomeService\u003e();\n\n// Typescript will infer the type so you don't need to specify the type of the mock\nconst mock = SafeMock.build\u003cSomeService\u003e();\n```\n\n##### Creating Mocks of classes\n```typescript\nimport SafeMock, {Mock} from \"safe-mock\";\n\nclass SomeServiceClass {\n    createSomething(argument: number) {\n        return 106;\n    }\n}\n\n// mock a class by passing the class into the build method\nconst mock: Mock\u003cSomeServiceClass\u003e = SafeMock.build(SomeServiceClass);\n\n// mock a class by passing the type of the mock as a generic to the build method  \nconst mock: Mock\u003cSomeServiceClass\u003e = SafeMock.build\u003cSomeServiceClass\u003e();\n\n//Typescript will infer the type so you don't need to specify the type of the mock\nconst mock = SafeMock.build\u003cSomeService\u003e();\n```\n\n##### Creating Mocks of functions\n```typescript\nimport SafeMock, {Mock} from \"safe-mock\";\n\nfunction someFunc() {\n} \n\n// Mock a function by passing it into the mockFunction method \nconst mockFunction = SafeMock.mockFunction(someFunc);\n\n// if you have a type signature for a function you can use generics to create a mockFunction\ntype FunctionToMock = () =\u003e string;\nconst mockFunction = SafeMock.mockFunction\u003cFunctionToMock\u003e();\n\n// you can pass a name into the mockFunction method to make debugging easier\ntype FunctionToMock = () =\u003e string;\nconst mockFunction = SafeMock.mockFunction\u003cFunctionToMock\u003e(\"nameOfFunc\");\n```\n\n\n### Specifying behavior for mocks\n##### Setting Return Values\n\n```typescript\nimport SafeMock, {Mock, when} from \"safe-mock\";\n\ninterface SomeService {\n    someMethod(argument: number, otherArg: string): string;\n}\nconst mock: Mock\u003cSomeService\u003e = SafeMock.build\u003cSomeService\u003e();\n\n// specify return values only when mocks are called with certain arguments like this\nwhen(mock.someMethod(123, \"some arg\")).return(\"expectedReturn\"); \n\n// if you don't care what arguments a mock receives you can specify a return value for all calls\nwhen(mock.someMethod).return(\"expectedReturn\"); \n```\n\n##### Making mocks throw Exceptions\n\n```typescript\nimport SafeMock, {Mock, when} from \"safe-mock\";\n\ninterface SomeService {\n    someMethod(argument: number, otherArg: string): string;\n}\nconst mock: Mock\u003cSomeService\u003e = SafeMock.build\u003cSomeService\u003e();\n\n// specify thrown exceptions only when mocks are called with certain arguments like this\nwhen(mock.someMethod(123, \"some arg\")).throw(new Error(\"BRR! Its cold!\")); \n\n//if you don't care what arguments a mock receives you can specify a thrown exceptions for all calls\nwhen(mock.someMethod).throw(new Error(\"BRR! Its cold!\")); \n```\n\n##### Working with mocks that return a Promise \n\n```typescript\nimport SafeMock, {Mock, when} from \"safe-mock\";\n\ninterface SomeService {\n    someMethod(argument: number): Promise\u003cstring\u003e;\n}\nconst mock: Mock\u003cSomeService\u003e = SafeMock.build\u003cSomeService\u003e();\n\n// specify that the mock returns rejected promises with a rejected value with reject\nwhen(mock.someMethod(123)).reject(new Error(\"BRR! Its cold!\"));\n\nmock.someMethod(123); //returns Promise.reject(new Error(\"BRR! Its cold!\"));\n\n// specify that the mock returns resolved promises with resolve\nwhen(mock.someMethod(124)).resolve(\"Hooray! You passed in 124\"); \n\nmock.someMethod(124); //returns Promise.resolve(\"Hooray! You passed in 124\");\n```\nNote: resolve() and reject() are only available on mocks that return a Promise.\n\n### Verifying behavior with mocks\n\n##### Verify that the correct arguments were used\n```typescript\nimport SafeMock, {verify} from \"safe-mock\";\n\ninterface SomeService {\n    someMethod(argument: number, otherArg: string): string;\n}\nconst mock = SafeMock.build\u003cSomeService\u003e();\n\n//use verify.calledWith to check the exact arguments to a mocked method\nverify(mock.someMethod).calledWith(123, \"someArg\");\n\n//use verify.called() to check that a mock was called at least once\nverify(mock.someMethod).called();\n\n\n//use verify.times(argument: number).called() to check that a mock was called a specified number of times\nverify(mock.someMethod).times(2).called();\n\n\n//use verify.times(argument: number).calledWith to check mocked method was called a specified number of times with\n//the exact arguments\nverify(mock.someMethod).times(4).calledWith(123, \"someArg\");\n```\n\n##### Verify that mocks were never called\n```typescript\nimport SafeMock, {verify} from \"safe-mock\";\n\ninterface SomeService {\n    someMethod(argument: number): string;\n}\nconst mock = SafeMock.build\u003cSomeService\u003e();\n\n//use verify.never to check that a method was never called with any arguments.\nverify(mock.someMethod).never.called();\n\n//use verify.never.calledWith to check that a mock was never called with specific arguments\nverify(mock.someMethod).never.calledWith(123);\n```\n\n##### Working with optional parameters\n```typescript\nimport SafeMock, {verify} from \"safe-mock\";\n\ninterface SomeService {\n    someMethod(argument?: number, otherArg?: string): string;\n}\nconst mock = SafeMock.build\u003cSomeService\u003e();\n\n//use verify.unsafe when working with optional parameters\n//unfortunately, type safety is lost when using 'verify.unsafe'  \nverify.unsafe(mock.someMethod).calledWith(123, \"someArg\");\nverify.unsafe(mock.someMethod).calledWith(123);\nverify.unsafe(mock.someMethod).called();\n\n```\n\n### Reset-ing mocks\n\n##### Use resetMock() to reset call information and mocked behavior\n```typescript\nimport SafeMock, {verify} from \"safe-mock\";\n\ninterface SomeService {\n    someMethod(argument: number, otherArg: string): string;\n    someOtherMethod(): string;\n}\nconst mock = SafeMock.build\u003cSomeService\u003e();\n\n//use resetMock() to a reset all methods on a mock\nmock.resetMock()\n\n//use resetMock() on an individual method to only reset that method\nmock.someOtherMethod.resetMock()\n```\n\n\n### Use mock functions just like mocked methods.\n```typescript\nimport SafeMock, {verify, when} from \"safe-mock\";\n\nfunction someFunction() {\n    return \"string\"\n}\n\nconst mockFunction = SafeMock.mockFunction(someFunction);\n\nwhen(mockFunction).return(\"return values\");\nverify(mockFunction).called()\nsomeOtherMethod.resetMock();\n```\n\n## Rely On the Typescript Compiler to prevent mistakes \n\nSafeMock won't let you return the wrong type from mocks.\n```typescript\ninterface SomeService {\n    createSomething(): string;\n}\n\nconst mock: Mock\u003cSomeService\u003e = SafeMock.build\u003cSomeService\u003e();\n\n//Won't compile createSomething returns a string\nwhen(mock.createSomething()).return(123); \n```\n\nSafeMock won't let you verify arguments of the wrong type.\n```typescript\ninterface SomeService {\n    createSomethingWithAString(argument: string): string;\n}\n\nconst mock: Mock\u003cSomeService\u003e = SafeMock.build\u003cSomeService\u003e();\n\nmock.createSomethingNoArgs();\n\n//Won't compile, createSomething takes a string\nverify(mock.createSomethingNoArgs).calledWith(123); \n```\n\nSafeMock won't let you verify the wrong number of arguments.\n```typescript\ninterface SomeService {\n    createSomethingNoArgs(): string;\n}\n\nconst mock: Mock\u003cSomeService\u003e = SafeMock.build\u003cSomeService\u003e();\n\nmock.createSomethingNoArgs();\n\n//Won't compile, createSomething takes no args\nverify(mock.createSomethingNoArgs).calledWith(123); \n```\n\nSafeMock won't let you verify non mocked methods.\n```typescript\nconst notAMock = {\n    blah() {}\n};\n\n//Won't compile notAMock.blah is not a mock\nverify(notAMock.blah).called(); \n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthewmcnew%2Fsafe-mock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatthewmcnew%2Fsafe-mock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthewmcnew%2Fsafe-mock/lists"}