UNPKG

8.33 kBMarkdownView Raw
1# Typescript Mock Imports
2
3#### Intuitive mocking for Typescript class imports.
4
5[![Build Status](https://travis-ci.org/EmandM/ts-mock-imports.svg)](https://travis-ci.org/EmandM/ts-mock-imports)
6
7<!-- TOC -->
8
9- [Typescript Mock Imports](#typescript-mock-imports)
10 - [Intuitive mocking for Typescript class imports.](#intuitive-mocking-for-typescript-class-imports)
11 - [Installation](#installation)
12 - [About](#about)
13 - [Usage](#usage)
14 - [API](#api)
15 - [ImportMock](#importmock)
16 - [MockManager (and MockStaticManager)](#mockmanager-and-mockstaticmanager)
17 - [OtherManager](#othermanager)
18 - [Test](#test)
19 - [Typescript Tests](#typescript-tests)
20 - [Unit Tests](#unit-tests)
21
22<!-- /TOC -->
23
24## Installation
25
26`npm install ts-mock-imports --save-dev`
27
28## About
29
30ts-mock-imports is useful if you want to replace classes that are exported from local files with stub versions of those classes. This allows ES6 code to be easily unit-tested without the need for a dependency injection library.
31
32ts-mock-imports is built on top of sinon.
33
34The mocked class takes all of the original class functions, and replaces them with noop functions (functions returning `undefined`).
35
36This library needs to be run on TypeScript 2.6.1 or later.
37
38## Usage
39
40`src/foo.ts`
41```javascript
42export class Foo {
43 constructor() {
44 throw new Error();
45 }
46}
47```
48
49`src/bar.ts`
50```javascript
51import { Foo } from './foo';
52
53export class Bar {
54 constructor() {
55 const foo = new Foo();
56 }
57}
58```
59
60`test/bar.spec.ts`
61```javascript
62import { ImportMock } from 'ts-mock-imports';
63import { Bar } from './Bar';
64import * as fooModule from '../src/foo';
65
66// Throws error
67const bar = new Bar();
68
69const mockManager = ImportMock.mockClass(fooModule, 'Foo');
70
71// No longer throws an error
72const bar = new Bar();
73
74// Call restore to reset to original imports
75mockManager.restore();
76```
77
78## API
79
80### ImportMock
81
82**`mockClass(module: <import * as>, importName?: string ): MockManager<T>`**
83
84**module:**
85
86The module containing the class you would like to mock.
87
88Both 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'`.
89
90**importName:**
91
92What the class is exported as. If exported using `export default` then this parameter is not needed.
93
94Using importName:
95```javascript
96// export class Foo
97import * as fooModule from '../src/foo';
98
99const mockManager = ImportMock.mockClass(fooModule, 'Foo');
100```
101
102Default imports:
103```javascript
104// export default Foo
105import * as foo from '../foo';
106
107const mockManager = ImportMock.mockClass(foo);
108```
109
110Import 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.
111
112Explicit typing:
113```javascript
114import * as fooModule from '../foo';
115
116const mockManager = ImportMock.mockClass<fooModule.Foo>(fooModule, 'Foo');
117```
118
119If you wish to ensure that `Foo` is the correct name for the mocked class, give import mock the type of your module.
120
121Explicit typing with full type assurance
122```javascript
123import * as fooModule from '../foo';
124
125const mockManager = ImportMock.mockClass<fooModule.Foo, typeof fooModule>(fooModule, 'Foo');
126
127// Will result in a TS Error as Bar is not exported by Foo
128const mockManager = ImportMock.mockClass<fooModule.Foo, typeof fooModule>(fooModule, 'Bar');
129```
130
131---
132
133**`mockStaticClass(module: <import * as>, importName?: string ): MockStaticManager<T>`**
134
135Takes the same arguments as `mockClass` but only replaces static functions on the original class.
136
137Static classes:
138(Only recreates static methods)
139```javascript
140import * as fooModule from '../foo';
141
142const mockManager = ImportMock.mockStaticClass(fooModule, 'Foo');
143```
144
145---
146
147**`mockFunction(module: <import * as>, importName?: string, returns?: any): SinonStub`**
148
149Returns a SinonStub that is set up to return the optional argument.
150
151Call restore on the stub object to restore the original export.
152
153Function exports:
154```javascript
155import * as fooModule from '../foo';
156
157const stub = ImportMock.mockFunction(fooModule, 'fooFunction', 'bar');
158// fooFunction will now return bar
159
160stub.restore()
161```
162
163---
164
165**`mockOther(module: <import * as>, importName?: string, replaceWith: any): OtherManager<T>`**
166
167`mockOther()` uses the replaceWith argument to entirely replace the original exported item.
168
169Useful for mocking out or removing variables and enums.
170
171Variable mocking:
172```javascript
173import * as fooModule from '../foo';
174
175const mockManager = ImportMock.mockOther(fooModule, 'fooName', 'fakeName');
176// import { fooName } from './foo' now returns 'fakeName'
177```
178
179---
180
181### MockManager (and MockStaticManager)
182
183**`MockManager<T>.mock(functionName: string, returns?: any): SinonStub`**
184
185This function returns a sinon stub object.
186
187**functionName:**
188
189The name of the function you would like to mock.
190
191If using MockManager, Typescript expects the functionName to match functions available on the original class.
192
193MockStaticManager allows any string.
194
195**returns:**
196
197The value returned when the mocked function is called.
198
199
200Mocking functions:
201(Returns a sinon stub)
202```javascript
203import * as fooModule from '../foo';
204
205const fooManager = ImportMock.mockClass(fooModule, 'Foo');
206
207// Will throw a type error if bar() does not exist on Foo
208const sinonStub = fooManager.mock('bar');
209```
210
211Mocking functions with a return object:
212```javascript
213import * as fooModule from '../foo';
214
215const mockManager = ImportMock.mockClass(fooModule, 'Foo');
216
217const returnVal = 'Bar';
218const sinonStub = mockManager.mock('bar', returnVal);
219// new Foo().bar() now returns 'Bar'
220```
221
222---
223
224**`MockManager<T>.set(varName: string, replaceWith?: any): void`**
225
226Replaces a property with a given value.
227
228**varName**
229
230The name of the property you would like to mock.
231
232If using MockManager, Typescript expects the varName to match properties available on the original class.
233
234MockStaticManager allows any string.
235
236**replaceWith:**
237
238The mock value of the property.
239
240
241Mocking variable with a return object:
242```javascript
243import * as fooModule from '../foo';
244
245const mockManager = ImportMock.mockClass(fooModule, 'Foo');
246
247const newVal = 5;
248mockManager.set('count', newVal);
249// new Foo().count now returns 5
250```
251
252---
253
254**`MockManager<T>.getMockInstance(): T`**
255
256Returns an instance of the mocked class.
257```javascript
258import * as fooModule from '../foo';
259
260const mockManager = ImportMock.mockClass(fooModule, 'Foo');
261
262const sinonStub = mockManager.mock('bar', 'Bar');
263const mockFoo = mockManager.getMockInstance();
264mockFoo.bar() // returns 'Bar'
265```
266---
267
268**`MockManager<T>.restore()`**
269
270Restores the import back to the original class.
271
272It is important that this is called so future imports work as expected.
273
274---
275
276### OtherManager
277
278**`OtherManager<T>.set(replaceWith?: T): void`**
279
280Replaces an exported property with a given value.
281
282This value must match the type of the original export.
283
284**replaceWith:**
285
286The mock value of the export.
287
288
289Mocking variable with a return object:
290```javascript
291import * as fooModule from '../foo';
292
293const mockManager = ImportMock.mockOther(fooModule, 'FooName', 'fakeName');
294// import { FooName } from './foo' imports 'fakeName'
295
296const newVal = 'newName';
297mockManager.set(newVal);
298// import { FooName } from './foo' now imports 'newName'
299```
300
301---
302
303**`OtherManager<T>.getValue(): T`**
304
305Returns the current mockValue
306```javascript
307import * as fooModule from '../foo';
308
309const mockManager = ImportMock.mockOther(fooModule, 'FooName', 'fakeName');
310
311mockManager.getValue(); // returns 'fakeName'
312```
313---
314
315**`OtherManager<T>.restore()`**
316
317Restores the import back to the original class.
318
319It is important that this is called so future imports work as expected.
320
321
322
323## Test
324
325```
326npm run test
327```
328
329### Typescript Tests
330
331```
332npm run dtslint
333```
334
335### Unit Tests
336
337```
338npm run unit-test
339```
\No newline at end of file