UNPKG

4.2 kBMarkdownView Raw
1# ineeda
2
3[![npm version](https://img.shields.io/npm/v/ineeda.svg)](https://img.shields.io/npm/v/ineeda.svg)
4
5Auto-mocking with [Proxies](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy)! Works best with TypeScript, but works just as well with JavaScript!
6
7# Installation:
8
9```
10npm install ineeda --save-dev
11```
12or
13```
14yarn add ineeda --dev
15```
16
17# Mocking:
18
19### To get a mock of a concrete class:
20
21```typescript
22import { Hero } from './Hero';
23
24import { ineeda } from 'ineeda';
25
26let hero: Hero = ineeda<Hero>();
27console.log(hero.age); // [IneedaProxy] (truthy!)
28console.log(hero.weapon.isMagic); // [IneedaProxy] (truthy!)
29console.log(hero.weapon.sharpen()); // Error('"sharpen" is not implemented.');
30
31let bonnie: Hero = ineeda<Hero>({ name: 'Bonnie' });
32console.log(bonnie.name); // 'Bonnie'
33```
34
35### To get a mock of an interface:
36
37```typescript
38import { IHorse } from './IHorse';
39
40import { ineeda } from 'ineeda';
41
42let horse: IHorse = ineeda<IHorse>();
43horse.hero.weapon.sharpen(); // Error('"sharpen" is not implemented.');
44```
45
46### To get a mock of a concrete class that is an actual instance of that class:
47
48```typescript
49import { Hero } from './Hero';
50
51import { ineeda } from 'ineeda';
52
53let realHero: Hero = ineeda.instanceof<Hero>(Hero);
54console.log(realHero instanceof Hero); // true;
55```
56
57### To get a factory that produces mocks of a concrete class:
58
59```typescript
60import { Hero } from './Hero';
61
62import { ineeda, IneedaFactory } from 'ineeda';
63
64let heroFactory: IneedaFactory<Hero> = ineeda.factory<Hero>();
65let heroMock: Hero = heroFactory();
66```
67
68# Intercepting:
69
70### Overriding proxied values:
71
72Since the result of a call to `ineeda` is a proxy, it will happily pretend to be any kind of object you ask it to be! That can cause some issues, such as when dealing with `Promises` or `Observables`. To get around that, you can use `intercept`.
73
74When you need a fake `Promise` or `Observable`:
75
76```typescript
77let mockObject = ineeda<MyObject>();
78
79function looksLikePromise (obj) {
80 return !!obj.then;
81}
82
83looksLikePromise(mockObject); // true;
84looksLikePromise(mockObject.intercept({ then: null })); // false;
85
86let mockObject = ineeda<MyObject>();
87let myObservable$ = Observable.of(mockObject.intercept({ schedule: null }));
88```
89
90Remembering which properties need to be intercepted can be a pain, and rather error prone. Alternatively, you can assign a `key`, which you can use to set up specific values that should be intercepted. In your test config you might do something like the following:
91
92```typescript
93// Prevent Bluebird from thinking ineeda mocks are Promises:
94ineeda.intercept<Promise<any>>(Promise, { then: null });
95
96// Prevent RxJS from thinking ineeda mocks are Schedulers:
97ineeda.intercept<Scheduler>(Observable, { schedule: null });
98```
99
100Then later, in your tests, you could do the following:
101
102```typescript
103let mockObject = ineeda<MyObject>();
104
105function looksLikePromise (obj) {
106 return !!obj.then;
107}
108
109looksLikePromise(mockObject); // true;
110looksLikePromise(mockObject.intercept(Promise)); // false;
111
112let mockObject = ineeda<MyObject>();
113let myObservable$ = Observable.of(mockObject.intercept(Observable));
114```
115
116You can also *globally* intercept something on all objects, by using the `intercept` method without the `key`:
117
118```typeScript
119ineeda.intercept({
120 // Prevent zone.js from thinking ineeda mocks are unconfigurable:
121 __zone_symbol__unconfigurables: null
122});
123```
124
125### Adding behaviour to proxied values:
126
127`intercept` can also be used to augment the behaviour of all mocks. One example might be to make every mocked function a `spy`.
128
129```typescript
130// Prevent sinon from thinking ineeda mocks are already spies:
131ineeda.intercept({
132 restore: null,
133 calledBefore: null
134});
135
136// Intercept all values that are functions and turn it into a stub:
137ineeda.intercept((value, key: string, values, target) => {
138 if (value instanceof Function) {
139 target[key] = () => { };
140 return sinon.stub(target, key, values[key]);
141 }
142 return value;
143});
144
145let mockObject = ineeda<MyObject>();
146mockObject.someMethod(1, 2, 3);
147
148// Using sinon-chai:
149expect(mockObject.someMethod).to.have.been.calledWith(1, 2, 3);
150```