|
4 | 4 | [](https://www.npmjs.com/package/testdouble)
|
5 | 5 | [](https://codeclimate.com/github/testdouble/testdouble.js/coverage)
|
6 | 6 |
|
7 |
| -Welcome! Are you writing JavaScript tests and in the market for a mocking library to |
8 |
| -fake out real things for you? testdouble.js is an opinionated, carefully-designed |
9 |
| -test double library maintained by, oddly enough, a software agency that's also |
10 |
| -named [Test Double](http://testdouble.com). |
| 7 | +Welcome! Are you writing JavaScript tests and in the market for a mocking |
| 8 | +library to fake out real things for you? testdouble.js is an opinionated, |
| 9 | +carefully-designed test double library maintained by, oddly enough, a software |
| 10 | +agency that's also named [Test Double](http://testdouble.com). |
11 | 11 |
|
12 | 12 | If you practice test-driven development, testdouble.js was designed to promote
|
13 | 13 | terse, clear, and easy-to-understand tests. There's an awful lot to cover, so
|
14 |
| -please take some time and enjoy our documentation, which itself is designed to |
15 |
| -show you how to make the most out of test doubles in your tests. |
| 14 | +please take some time and enjoy our documentation, which is designed to show you |
| 15 | +how to make the most out of test doubles in your tests. |
16 | 16 |
|
17 |
| -## The pitch |
| 17 | +This library was designed to work for both Node.js and browser interpeters and |
| 18 | +to be test-framework agnostic, so you can plop it into a codebase using Jasmine, |
| 19 | +Mocha, Tape, Jest, or our own |
| 20 | +[teenytest](https://github.com/testdouble/teenytest). |
18 | 21 |
|
19 |
| -Interested in learning what testdouble.js is, why it exists, and what the API |
20 |
| -offers? The quickest path is this fast-paced 20-minute talk: |
| 22 | +## Install |
21 | 23 |
|
22 |
| -[<img width="633" alt="screenshot of testdouble.js talk" src="https://cloud.githubusercontent.com/assets/79303/16356401/1a9d7ffc-3aa4-11e6-833f-9d6094547297.png"> |
23 |
| -](https://vimeo.com/169413322) |
| 24 | +```js |
| 25 | +npm install -D testdouble |
| 26 | +``` |
| 27 | + |
| 28 | +If you just want to fetch the browser distribution, you can also get it from |
| 29 | +[unpkg](https://unpkg.com/testdouble/dist/) |
| 30 | + |
| 31 | +We recommend requiring the library in a test helper and setting it globally for |
| 32 | +convenience to the shorthand `td`: |
| 33 | + |
| 34 | +```js |
| 35 | +global.td = require('testdouble') // Node.js; `window.td` for browsers |
| 36 | +``` |
| 37 | + |
| 38 | +(You may need to declare the global in order to make your linter handy. |
| 39 | +Instructions: |
| 40 | +[eslint](https://eslint.org/docs/user-guide/configuring#specifying-globals), |
| 41 | +[Standard](https://github.com/standard/standard/#i-use-a-library-that-pollutes-the-global-namespace-how-do-i-prevent-variable-is-not-defined-errors).) |
| 42 | + |
| 43 | +## Getting started |
| 44 | + |
| 45 | +Mocking libraries are more often abused than used effectively, so figuring out |
| 46 | +how to document a mocking library that is designed to encourage only productive |
| 47 | +use has been a real challenge. Here are a few paths to getting started: |
| 48 | + |
| 49 | +* The [API section of this README](#api) to get an at-a-glance view of |
| 50 | + the API so you can get started stubbing and verifying right away |
| 51 | +* A [20-minute |
| 52 | + video](http://blog.testdouble.com/posts/2016-06-05-happier-tdd-with-testdouble-js) |
| 53 | + overview of the library, its goals, and the basics of its API |
| 54 | +* A [comparison between testdouble.js and |
| 55 | + Sinon.js](http://blog.testdouble.com/posts/2016-03-13-testdouble-vs-sinon.html), |
| 56 | + in case you've already got experience working with Sinon and you're looking |
| 57 | + for a high-level overview of the differences |
| 58 | +* The full testdouble.js [documentation](/docs), which is quite lengthy, but |
| 59 | + will do a thorough job to explain when to (and when not to) take advantage of |
| 60 | + the various faetures of testdouble.js. Its outline is at the [bottom of this |
| 61 | + README](#docs) |
| 62 | + |
| 63 | +## API |
| 64 | + |
| 65 | +### `td.replace()` for replacing dependencies |
| 66 | + |
| 67 | +The first thing a test double library needs to do is give you a way to replace |
| 68 | +the production dependencies of your [subject under |
| 69 | +test](https://github.com/testdouble/contributing-tests/wiki/Subject) with fake |
| 70 | +ones created by the library. |
| 71 | + |
| 72 | +testdouble.js provides a top-level method called `td.replace()` |
| 73 | + |
| 74 | +#### Module replacement with Node.js |
| 75 | + |
| 76 | +If you're using Node.js and don't mind using the CommonJS `require` method in |
| 77 | +your tests (you can still use `import`/`export` in your production code, |
| 78 | +assuming you're compiling it down for consumption by your tests), testdouble.js |
| 79 | +uses a library we wrote called [quibble](https://github.com/testdouble/quibble) |
| 80 | +to monkey-patch the `require()` feature so that your subject will automatically |
| 81 | +receive your faked dependencies simply by requiring them. (If you've used |
| 82 | +something like [proxyquire](https://github.com/thlorenz/proxyquire), this is |
| 83 | +like a slightly terser form of that) |
| 84 | + |
| 85 | +Here's an example of using `td.replace` in the setup of a test of a Node.js |
| 86 | +module: |
| 87 | + |
| 88 | +```js |
| 89 | +let loadsPurchases, generatesInvoice, sendsInvoice, subject |
| 90 | +module.exports = { |
| 91 | + beforeEach: () => { |
| 92 | + loadsPurchases = td.replace('../src/loads-purchases') |
| 93 | + generatesInvoice = td.replace('../src/generates-invoice') |
| 94 | + sendsInvoice = td.replace('../src/sends-invoice') |
| 95 | + subject = require('../src/index') |
| 96 | + } |
| 97 | + //… |
| 98 | +} |
| 99 | +``` |
24 | 100 |
|
25 |
| -## Coming from Sinon.js? |
| 101 | +Things to remember about replacing Node.js modules: |
26 | 102 |
|
27 |
| -Right now, Sinon.js is the test double incumbent in JavaScript, with over 1.7 |
28 |
| -million downloads in the last month. If you've got experience with Sinon, [check |
29 |
| -out our side-by-side |
30 |
| -comparison](http://blog.testdouble.com/posts/2016-03-13-testdouble-vs-sinon.html) |
31 |
| -to see why we wrote testdouble.js and how some of the API translates. |
| 103 | +* The test must `td.replace` and `require` everything in a before-each hook, |
| 104 | +in order to bypass Node's module cache and avoid test pollution |
| 105 | +* Relative paths to each replaced dependency are relative *from the test listing |
| 106 | + to the dependency*. This runs counter to how some other tools do it, but we |
| 107 | + feel it makes more sense |
| 108 | +* The test suite (usually in a global after-each hook) must call `td.reset()` to |
| 109 | +avoid test pollution |
32 | 110 |
|
33 |
| -## The Very Basics |
| 111 | +#### Property replacement |
34 | 112 |
|
35 |
| -Before diving into our in-depth docs, here is a quick intro of the basic uses: |
| 113 | +If you're running tests outside Node.js or otherwise injecting dependencies |
| 114 | +manually (or with a DI tool like |
| 115 | +[dependable](https://github.com/testdouble/dependable)), then you can still use |
| 116 | +`td.replace` to automatically replace and imitate |
36 | 117 |
|
37 | 118 | ### Stubbing return values for functions
|
38 | 119 |
|
|
0 commit comments