{"id":13912674,"url":"https://github.com/EmandM/ts-mock-imports","last_synced_at":"2025-07-18T12:32:17.724Z","repository":{"id":46244394,"uuid":"134883462","full_name":"EmandM/ts-mock-imports","owner":"EmandM","description":"Intuitive mocking library for Typescript class imports","archived":false,"fork":false,"pushed_at":"2024-07-10T18:34:23.000Z","size":10595,"stargazers_count":109,"open_issues_count":1,"forks_count":8,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-11-14T12:56:59.079Z","etag":null,"topics":["dependency-injection","es6-classes","es6-import","fake","mock","mock-class","mock-functions","mock-imports","sinon","sinon-stub","stub","testing-tools","tests","typescript","typescript-library","typescript2","typescript3"],"latest_commit_sha":null,"homepage":null,"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/EmandM.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-25T17:00:22.000Z","updated_at":"2024-09-16T18:20:30.000Z","dependencies_parsed_at":"2024-01-14T08:48:23.161Z","dependency_job_id":"85cc4d6b-892d-48fd-8320-309898f142bf","html_url":"https://github.com/EmandM/ts-mock-imports","commit_stats":{"total_commits":89,"total_committers":7,"mean_commits":"12.714285714285714","dds":0.3595505617977528,"last_synced_commit":"ae6284f93367febb16eea2533350f81642597d4d"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmandM%2Fts-mock-imports","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmandM%2Fts-mock-imports/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmandM%2Fts-mock-imports/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmandM%2Fts-mock-imports/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EmandM","download_url":"https://codeload.github.com/EmandM/ts-mock-imports/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226409839,"owners_count":17620717,"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":["dependency-injection","es6-classes","es6-import","fake","mock","mock-class","mock-functions","mock-imports","sinon","sinon-stub","stub","testing-tools","tests","typescript","typescript-library","typescript2","typescript3"],"created_at":"2024-08-07T01:01:43.532Z","updated_at":"2025-07-18T12:32:17.714Z","avatar_url":"https://github.com/EmandM.png","language":"TypeScript","funding_links":[],"categories":["typescript","TypeScript"],"sub_categories":[],"readme":"# Typescript Mock Imports\r\n\r\n#### Intuitive mocking for Typescript imports.\r\n\r\n[![npm](https://img.shields.io/npm/v/ts-mock-imports.svg)](https://www.npmjs.com/package/ts-mock-imports) [![Build Status](https://github.com/EmandM/ts-mock-imports/actions/workflows/release-and-publish.yml/badge.svg)](https://github.com/EmandM/ts-mock-imports/actions/workflows/release-and-publish.yml) [![Test Status](https://github.com/EmandM/ts-mock-imports/actions/workflows/test.yml/badge.svg)](https://github.com/EmandM/ts-mock-imports/actions/workflows/test.yml)\r\n\r\n## About\r\n\r\nts-mock-imports leverages the ES6 `import` syntax to mock out imported code with stub versions of the imported objects. This allows ES6 code to be easily unit-tested without the need for an explicit dependency injection library.\r\n\r\nts-mock-imports is built on top of sinon. [Sinon stub documentation](https://sinonjs.org/releases/latest/stubs/)\r\n\r\nMocked classes take all of the original class functions, and replace them with noop functions (functions returning `undefined`) while maintaining type safety.\r\n\r\nThis library needs to be run on TypeScript 2.6.1 or later.\r\n\r\n- [Typescript Mock Imports](#typescript-mock-imports)\r\n      - [Intuitive mocking for Typescript imports.](#intuitive-mocking-for-typescript-imports)\r\n  - [About](#about)\r\n  - [Installation](#installation)\r\n  - [Usage](#usage)\r\n  - [API](#api)\r\n    - [ImportMock](#importmock)\r\n    - [MockManager (and MockStaticManager)](#mockmanager-and-mockstaticmanager)\r\n    - [OtherManager](#othermanager)\r\n  - [Limitations](#limitations)\r\n  - [`TypeError: Cannot set property TestClass of #\u003cObject\u003e which has only a getter`](#typeerror-cannot-set-property-testclass-of-object-which-has-only-a-getter)\r\n    - [InPlaceMockManager](#inplacemockmanager)\r\n    - [InPlaceMockManager API](#inplacemockmanager-api)\r\n  - [Contributing](#contributing)\r\n    - [Test](#test)\r\n    - [Releasing](#releasing)\r\n\r\n## Installation\r\n\r\nts-mock-imports is built on top of Sinon and TypeScript. Ensure you have both installed.\r\n\r\n```bash\r\nnpm install typescript\r\n\r\nnpm install sinon --save-dev\r\n```\r\n\r\nInstall the library\r\n\r\n```\r\nnpm install ts-mock-imports --save-dev\r\n```\r\n\r\n## Usage\r\n\r\n`src/foo.ts`\r\n```typescript\r\nexport class Foo {\r\n  private count: number;\r\n  constructor() {\r\n    throw new Error();\r\n  }\r\n\r\n  public getCount(): number {\r\n    return count;\r\n  }\r\n}\r\n```\r\n\r\n`src/bar.ts`\r\n```typescript\r\nimport { Foo } from './foo';\r\n\r\nexport class Bar {\r\n  constructor() {\r\n    const foo = new Foo();\r\n  }\r\n}\r\n```\r\n\r\n`test/bar.spec.ts`\r\n```typescript\r\nimport { ImportMock } from 'ts-mock-imports';\r\nimport { Bar } from '../src/bar';\r\nimport * as fooModule from '../src/foo';\r\n\r\n// Throws error\r\nconst bar = new Bar();\r\n\r\nconst mockManager = ImportMock.mockClass(fooModule, 'Foo');\r\n\r\n// No longer throws an error\r\nconst bar = new Bar();\r\n\r\n// Easily add mock responses for testing\r\nmockmanager.mock('getCount', 3)\r\n\r\n// Call restore to reset all mocked objects to original imports\r\nImportMock.restore();\r\n```\r\n\r\n## API\r\n\r\n### ImportMock\r\n\r\n**`mockClass(module: \u003cimport * as\u003e, importName?: string ): MockManager\u003cT\u003e`**\r\n\r\n**module:**\r\n\r\nThe module containing the class you would like to mock.\r\n\r\nBoth the source file and test file need to use the same path to import the mocked module. I.e. Cannot use `'src/index'` to import into the `.spec.ts` file and then use `'src/foo'` to import into `bar.ts`. Both files need to use either `'src/foo'` or `'src/index'`.\r\n\r\n**importName:**\r\n\r\nWhat the class is exported as. If exported using `export default` then this parameter is not needed.\r\n\r\nUsing importName:\r\n```typescript\r\n// export class Foo\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockClass(fooModule, 'Foo');\r\n```\r\n\r\nDefault imports:\r\n```typescript\r\n// export default Foo\r\nimport * as foo from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockClass(foo);\r\n```\r\n\r\nImport mock will infer the type of `Foo` if it is the only item exported out of it's file. If more things are exported, you will need to  explicitly provide types to Import mock.\r\n\r\nExplicit typing:\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockClass\u003cfooModule.Foo\u003e(fooModule, 'Foo');\r\n```\r\n\r\nIf you wish to ensure that `Foo` is the correct name for the mocked class, give import mock the type of your module.\r\n\r\nExplicit typing with full type assurance\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockClass\u003cfooModule.Foo, typeof fooModule\u003e(fooModule, 'Foo');\r\n\r\n// Will result in a TS Error as Bar is not exported by Foo\r\nconst mockManager = ImportMock.mockClass\u003cfooModule.Foo, typeof fooModule\u003e(fooModule, 'Bar');\r\n```\r\n\r\n`mockClass` replaces the original export with a fake class. All original functions exist on the fake class as noop functions (functions returning `undefined`).\r\n\r\n---\r\n\r\n**`mockStaticClass(module: \u003cimport * as\u003e, importName?: string ): MockStaticManager\u003cT\u003e`**\r\n\r\nTakes the same arguments as `mockClass` but only replaces static functions on the original class.\r\n\r\nStatic classes:\r\n(Only recreates static methods)\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockStaticClass(fooModule, 'Foo');\r\n```\r\n\r\n---\r\n\r\n**`mockFunction(module: \u003cimport * as\u003e, importName?: string, returns?: any): SinonStub`**\r\n\r\nReturns a SinonStub that is set up to return the optional argument.\r\n\r\nCall restore on the stub object to restore the original export.\r\n\r\nFunction exports:\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst stub = ImportMock.mockFunction(fooModule, 'fooFunction', 'bar');\r\n// fooFunction will now return bar\r\n\r\nstub.restore()\r\n```\r\n\r\n---\r\n\r\n**`mockOther(module: \u003cimport * as\u003e, importName?: string, replaceWith: Partial\u003ctypeof module.importName\u003e): OtherManager\u003cT\u003e`**\r\n\r\n`mockOther()` uses the replaceWith argument to entirely replace the original exported item.\r\n\r\nUseful for mocking out or removing variables and enums.\r\n\r\nVariable mocking:\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockOther(fooModule, 'fooName', 'fakeName');\r\n// import { fooName } from './foo' now returns 'fakeName'\r\n```\r\n\r\n**replaceWith:**\r\n\r\nRequires an object that matches Partial\u003cOriginalType\u003e. This argument is an optional shorthand, and the value can be updated using mockManager.set().\r\n\r\n---\r\n\r\n**`restore(): void`**\r\n\r\n`restore()` will restore all mocked items. Allows `ImportMock` to be used as a sandbox.\r\n\r\nUseful for restoring when multiple mocks have been created.\r\n\r\nVariable mocking:\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\nimport * as bazModule from '../src/baz';\r\n\r\nImportMock.mockClass(fooModule, 'Foo');\r\nImportMock.mockClass(fooModule, 'OtherFoo');\r\nImportMock.mockFunction(bazModule, 'mainFunction')\r\n\r\n// \u003crun tests\u003e\r\n\r\nImportMock.restore()\r\n\r\n// all mocked imports will now be restored to their original values\r\n```\r\n\r\n\r\n---\r\n\r\n### MockManager (and MockStaticManager)\r\n\r\n**`MockManager\u003cT\u003e.mock(functionName: string, returns?: any): SinonStub`**\r\n\r\nReturns a sinon stub object.\r\n\r\n**functionName:**\r\n\r\nThe name of the function you would like to mock.\r\n\r\nIf using MockManager, Typescript expects the functionName to match functions available on the original class.\r\n\r\nMockStaticManager allows any string.\r\n\r\n**returns:**\r\n\r\nThe value returned when the mocked function is called.\r\n\r\nMocking functions:\r\n(Returns a sinon stub)\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst fooManager = ImportMock.mockClass(fooModule, 'Foo');\r\n\r\n// Will throw a type error if bar() does not exist on Foo\r\nfooManager.mock('bar');\r\n// new Foo().bar() will return undefined\r\n```\r\n\r\nMocking functions with a return object:\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockClass(fooModule, 'Foo');\r\n\r\nmockManager.mock('bar', 'Bar');\r\n// new Foo().bar() now returns 'Bar'\r\n```\r\n\r\nIf you wish to run modified code when the mocked function is called, you can use `sinon.callsFake()`\r\n```typescript\r\nconst mockManager = ImportMock.mockClass(fooModule, 'Foo');\r\nconst sinonStub = mockManager.mock('bar');\r\nsinonStub.callsFake(() =\u003e {\r\n  // custom code here\r\n})\r\n```\r\n\r\n---\r\n\r\n**`MockManager\u003cT\u003e.set(varName: string, replaceWith?: any): void`**\r\n\r\nReplaces a property with a given value.\r\n\r\n**varName**\r\n\r\nThe name of the property you would like to mock.\r\n\r\nIf using MockManager, Typescript expects the varName to match properties available on the original class.\r\n\r\nMockStaticManager allows any string.\r\n\r\n**replaceWith:**\r\n\r\nThe mock value of the property.\r\n\r\n\r\nMocking variable with a return object:\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockClass(fooModule, 'Foo');\r\n\r\nconst newVal = 5;\r\nmockManager.set('count', newVal);\r\n// new Foo().count now returns 5\r\n```\r\n\r\n---\r\n\r\n**`MockManager\u003cT\u003e.getMockInstance(): T`**\r\n\r\nReturns an instance of the mocked class.\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockClass(fooModule, 'Foo');\r\n\r\nconst sinonStub = mockManager.mock('bar', 'Bar');\r\nconst mockFoo = mockManager.getMockInstance();\r\nmockFoo.bar() // returns 'Bar'\r\n```\r\n---\r\n\r\n**`MockManager\u003cT\u003e.restore()`**\r\n\r\nRestores the import back to the original class.\r\n\r\nIt is important that this is called so future imports work as expected.\r\n\r\n---\r\n\r\n### OtherManager\r\n\r\n**`OtherManager\u003cT\u003e.set(replaceWith?: T): void`**\r\n\r\nReplaces an exported property with a given value.\r\n\r\nThis value must match the type of the original export.\r\n\r\n**replaceWith:**\r\n\r\nThe mock value of the export.\r\n\r\n\r\nMocking variable with a return object:\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockOther(fooModule, 'FooName', 'fakeName');\r\n// import { FooName } from './foo' imports 'fakeName'\r\n\r\nconst newVal = 'newName';\r\nmockManager.set(newVal);\r\n// import { FooName } from './foo' now imports 'newName'\r\n```\r\n\r\n---\r\n\r\n**`OtherManager\u003cT\u003e.getValue(): T`**\r\n\r\nReturns the current mockValue\r\n```typescript\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockOther(fooModule, 'FooName', 'fakeName');\r\n\r\nmockManager.getValue(); // returns 'fakeName'\r\n```\r\n---\r\n\r\n**`OtherManager\u003cT\u003e.restore()`**\r\n\r\nRestores the import back to the original class.\r\n\r\nIt is important that this is called so future imports work as expected.\r\n\r\n\r\n## Limitations\r\n\r\nImport mock works best when mocking es6 exports. Due to JavaScript's sometimes winding development history, there are some modules that use alternate export patterns that may not work correctly when mocked using Import mock. To reduce the chance of issues, all production code should aim to use `import { item } from 'module';` syntax. This allows the test code to use `import * as object from 'module';` syntax seamlessly.\r\n\r\nRequirejs is not currently compatible with this library.\r\n\r\n\r\n## `TypeError: Cannot set property TestClass of #\u003cObject\u003e which has only a getter`\r\n\r\n\r\nTypescript 3.9 introduced new functionality that blocks the key functionality of this library. With certain compilation structures, it is no longer possible to replace module exports.\r\n\r\nThere is no true workaround for this issue. A partial workaround has been implemented and is in an alpha testing stage.\r\n\r\n**Warning: The following functions are potentially risky and can lead to unexpected behaviour**\r\n\r\n\r\n### InPlaceMockManager\r\n\r\n```typescript\r\n// export class Foo\r\nimport * as fooModule from '../src/foo';\r\n\r\nconst mockManager = ImportMock.mockClassInPlace(fooModule, 'Foo');\r\n```\r\n\r\nThis replacement for `mockManager` does not replace the entire class, but instead replaces all functions on the given class **In Place**. This means the original constructor and any local class variables are left on the mocked class. `restore()` will replace all functions back to their original state, however it cannot guarantee that all internal variables are restored. As such, this function should be used with caution as memory can potentially leak between tests.\r\n\r\n`set()` is also not available on this manager.\r\n\r\nFor more information: [Issue 24](https://github.com/EmandM/ts-mock-imports/issues/24)\r\n\r\n### InPlaceMockManager API\r\n\r\n**`InPlaceMockManager\u003cT\u003e.mock(functionName: string, returns?: any): SinonStub`**\r\n\r\nReturns a sinon stub object.\r\n\r\n**functionName:**\r\n\r\nThe name of the function you would like to mock.\r\n\r\nIf using MockManager, Typescript expects the functionName to match functions available on the original class.\r\n\r\nMockStaticManager allows any string.\r\n\r\n**returns:**\r\n\r\nThe value returned when the mocked function is called.\r\n\r\nMocking functions:\r\n(Returns a sinon stub)\r\n\r\n```typescript\r\nconst mockManager = ImportMock.mockClassInPlace(fooModule, 'Foo');\r\nconst sinonStub = mockManager.mock('bar');\r\n```\r\n\r\n\r\n**`MockManager\u003cT\u003e.restore()`**\r\n\r\nRestores the import back to the original class.\r\n\r\nIt is important that this is called so future imports work as expected.\r\n\r\n**Warning: It is not guaranteed that `restore()` will completely restore the class definition**\r\n\r\n\r\n\r\n## Contributing\r\n\r\n### Test\r\n\r\nThis library contains two types of tests.\r\n1. Typescript tests to ensure typing works as intended: `npm run dtslint`\r\n2. Unit tests to check the runtime functionality of the library: `npm run unit-test`\r\n\r\nBoth test suites are run when using `npm run test`\r\n\r\n### Releasing\r\n\r\nRelease new versions to both npm and github using the [Setup Release](https://github.com/EmandM/ts-mock-imports/actions/workflows/release-and-publish.yml) action.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FEmandM%2Fts-mock-imports","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FEmandM%2Fts-mock-imports","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FEmandM%2Fts-mock-imports/lists"}