Testing your App
How to test your app
This guide shows you how to run a unit test on your app.

Requirements

Please make sure you meet the following dependencies. Visit the corresponding sites to follow how to set them up.
This guide is given with the assumption you have some knowledge of:
  • Typescript
  • Basic unit testing concepts

App Setup

On your .rcappsconfig add the following lines on the ignoredFiles array:
  1. 1.
    "/mocks/*"
  2. 2.
    "/tests/*"
  3. 3.
    "**/jest.config.js"

Testing

Say for example you have this app command to test:
HelpCommand.ts
1
import { IModify, IRead } from "@rocket.chat/apps-engine/definition/accessors";
2
import { SlashCommandContext } from "@rocket.chat/apps-engine/definition/slashcommands";
3
import { notifyUser } from "../lib/message";
4
import { BoilerplateApp } from "../BoilerplateApp";
5
6
class HelpCommand {
7
public async run({ app, context, read, modify }: { app: BoilerplateApp, context: SlashCommandContext, read: IRead, modify: IModify }): Promise<void> {
8
const room = context.getRoom();
9
const user = context.getSender();
10
11
const text =
12
`\`/boilerplate modal\` Opens a modal\n` +
13
`\`/boilerplate help\` Shows help message`;
14
15
await notifyUser({ app, read, modify, room, user, text });
16
}
17
}
18
19
export const helpCommand = new HelpCommand();
Copied!

Snippet Explanation

It's a common command that shows a helper to the user on how to use your app. First, decide what you want to test, and then you will see how.
This class HelpCommand has a single async method called run. Let's see how it works.
On both lines 8 and 9, the method is using the context parameter to get some information regarding room and sender.
On line 11 we just assign a string to a const and at the end of the method, it calls a function called notifyUser which sends the message to the user.

Testing

At the top of the file, set jest.autoMockOff(); and below will have an example on how to test your command and the explanation of what is happening on each line/block of code.
HelpCommand.spec.ts
1
jest.autoMockOff(); //1
2
const notifyUser = jest.fn();
3
jest.mock('@lib/message', () => ({ //2
4
notifyUser,
5
}));
6
import {
7
commandsMockParams,
8
roomMock,
9
userMock
10
} from '@commands/__mocks__/commands.mock'; //3
11
12
import { helpCommand } from '@commands/HelpCommand'; //4
13
14
describe('HelpCommand', () => { //5
15
test('should set tex with the right values', async () => { //6
16
await helpCommand.run(commandsMockParams); //7
17
const { app, modify, read } = commandsMockParams; //8
18
expect(notifyUser).toBeCalledWith({
19
app,
20
read,
21
modify,
22
room: roomMock,
23
text:
24
`\`/boilerplate modal\` Opens a modal\n` +
25
`\`/boilerplate help\` Shows help message`,
26
user: userMock,
27
}); //9
28
});
29
});
30
Copied!
  1. 1.
    The first step is very since it depends on how you set your jest.setup.js sometimes auto mock may help and sometimes not;
  2. 2.
    This part covers lines 3..5 which is the part that you will mock the method is called at the end of your method run;
The jest.mock will mock all methods/functions that are inside the path inserted on the parameter and the jest.fn() attributed on notifyUser allows you to test in your test case.
For deep documentation about mock a method please check here.
3. This part is just a form to organize all the mocks you will use on your test, since the run method need some parameters that have a lot of properties you may separate this on a file, below you will see an example:
commands.mock
1
const roomMock = {
2
id: '123',
3
displayName: 'nice display name',
4
slugifiedName: 'slugfied name',
5
type: 'type',
6
creator: {},
7
userIds: ['123', '234'],
8
isDefault: true,
9
isReadOnly: false,
10
displaySystemMessages: true,
11
messageCount: 1,
12
createdAt: 'Mon Nov 22 2021 15:22:49 GMT-0300 (Brasilia Standard Time)',
13
updatedAt: 'Mon Nov 22 2021 15:22:49 GMT-0300 (Brasilia Standard Time)',
14
lastModifiedAt: 'Mon Nov 22 2021 15:22:49 GMT-0300 (Brasilia Standard Time)',
15
description: 'desc',
16
17
};
18
19
const userMock = {
20
id: '567',
21
username: 'username',
22
emails: [],
23
type: 'nice type',
24
isEnabled: true,
25
name: 'name',
26
roles: 'admin',
27
status: 'Registered',
28
statusConnection: 'Online',
29
utcOffset: 'ZM',
30
createdAt: 'Mon Nov 22 2021 15:22:49 GMT-0300 (Brasilia Standard Time)',
31
updatedAt: 'Mon Nov 22 2021 15:22:49 GMT-0300 (Brasilia Standard Time)',
32
lastLoginAt: 'Mon Nov 22 2021 15:22:49 GMT-0300 (Brasilia Standard Time)',
33
appId: '678',
34
};
35
const commandsMockParams: {
36
app: WikipediaApp,
37
context: SlashCommandContext,
38
read: IRead,
39
modify: IModify,
40
http: IHttp
41
} = {
42
app: {
43
initialize: jest.fn(),
44
} as unknown as WikipediaApp,
45
context: {
46
getSender: jest.fn().mockReturnValue(userMock),
47
getRoom: jest.fn().mockReturnValue(roomMock),
48
getArguments: jest.fn().mockReturnValue(args),
49
getThreadId: jest.fn(),
50
getTriggerId: jest.fn(),
51
} as unknown as SlashCommandContext,
52
.
53
.
54
.
55
.
56
.
Copied!
4. Next, you only need to import the function or class that needs to be tested;
5. Set your describe to identify your test, for this example HelpCommand is fine;
6. At this point, you will describe your test cases, for this example, one is enough but it can be more, thinking that you may need to test multiple cases as errors or forks.
The test receives a string and a callback to run the test.
In some cases, the method/function that you are testing may be a Promise, so you can set the callback as async it will work in most of the cases, but some not, so for more information about testing async methods, please reach this link
7. This line you only need to call your method/function and in this particular case this is a void method it will be no need to attribute the result of your method in a variable;
8. This part only takes all the mocked values to check our methods;
9. This is the famous expect where you check if your method is working as it is supposed to do, in this case, we are checking if the notifyUser is been called with the right parameters.

Running your test

Run your test by following any of the two procedures
  • Using Terminal: Open up your terminal in the working directory and execute jest <file-name> or just jest to run all test files;
  • Using the VScode extension: You only need to install this vscode extension and all of your tests files appear as below:
Using extension to run the tests
Two buttons will appear upon tests so you can click run or debug and if everything went well you will see:
All tests succeed
For more information on how to run your tests please visit this link.

Conclusion

This documentation does not show all you can do with jest. Feel free to check out Jest documentation for other samples.