1 | # Automated tests for command handlers
|
2 |
|
3 | Test commands by testing the `handle` method. This section describes the Atomist team's testing style for commands, but there are many ways to test. If you already have a favorite TypeScript or JavaScript testing style and framework, use that.
|
4 |
|
5 | We use [Mocha](https://mochajs.org/) for unit tests in our automation clients, with [power-assert](https://github.com/power-assert-js/power-assert) for enhanced failure messages.
|
6 |
|
7 | Tests live in the `test/` directory. Run them with `npm run test`.
|
8 |
|
9 | Commands usually produce side-effects, so we test by passing fake
|
10 | objects to substitute for `messageClient`, `graphClient`,
|
11 | etc. Creating fakes is easy in a language like JavaScript or
|
12 | TypeScript.
|
13 |
|
14 | For instance, to test
|
15 | [a command](https://github.com/atomist/automation-client-samples-ts/blob/master/src/commands/simple/HelloChannel.ts)
|
16 | that sends a message to a Slack channel, make a fake `messageClient` that only
|
17 | has one function:
|
18 |
|
19 | ```typescript
|
20 | // create a fake message client.
|
21 | const fakeMessageClient = {
|
22 | addressChannels(message, channel) {
|
23 | this.channelThatWasSent = channel; // store what you care about
|
24 | return Promise.resolve(); // fake a return value
|
25 | },
|
26 | };
|
27 |
|
28 | // cast the context to the type we need
|
29 | const fakeContext = { messageClient: fakeMessageClient } as any as HandlerContext;
|
30 | ```
|
31 |
|
32 | Check out the
|
33 | [full test](https://github.com/atomist/automation-client-samples-ts/blob/master/test/commands/simple/HelloChannelTest.ts)
|
34 | for a full description.
|
35 |
|
36 | ### Testing editors and generators
|
37 |
|
38 | For commands that use automation-client functions to [create or change code](#make-a-code-change), we typically test
|
39 | only the project-editing function. There is an implementation of `Project` that is all in-memory, for easy testing.
|
40 | For example:
|
41 |
|
42 | ```typescript
|
43 | // describe each pretend file in the input project
|
44 | const project = InMemoryProject.of({ path: "README.md", content: "# This is the README" },
|
45 | { path: "package.json", content: `{ "name": "my-project" }`});
|
46 |
|
47 | const result = editProject(project,
|
48 | null, // context is not used
|
49 | { newYear: "2222" }); // parameters
|
50 | ```
|
51 |
|
52 | Check out the
|
53 | [whole example](https://github.com/atomist/automation-client-samples-ts/blob/master/test/commands/editor/UpdateCopyrightEditorTest.ts)
|
54 | in the samples.
|