-
Notifications
You must be signed in to change notification settings - Fork 395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding unit tests examples to the documentation #383
Comments
Thanks for using our project and giving us your feedback! I agree that some guidance around how to write tests for apps would be really helpful. We're making some progress towards establishing an easier technique in #353. Those changes will result in a Bolt v2, which we're hoping to release in a few weeks. So an update to our documentation about testing would make the most sense with or after that. |
Now that we're on version 2, can anyone share some examples of how they're doing unit testing? |
This library hasn't come up with Slack feature-specific testing supports yet but this 3rd party project may be worth checking. https://github.com/IBM/slack-wrench/tree/master/packages |
@RayBB a simple flow which works for me:
I can attach some code snippets if they may be useful But for sure using the tool mentioned by seratch would be more straightforward |
@szymon-szym some examples would be appreciated! |
Here's an example of how to fake a real call. Keep it simple, you don't always need a mocking framework try simple js, it usually works and pays off. // stub the real call
Code under test:
so rather than using something like You just care that the code inside your function (your behavior) (in my case Hope this helps anyone out there. |
@RayBB It was a while, but still it might be useful Here is a test:
Here is a code to be checked:
|
I recently created an open source app called Asking for a Friend, which was written in TypeScript, lifted with Eslint and Prettier, and has 99% test coverage via Jest. I figured out a new pattern for the declaration of listener methods and it's worked really well for me when it comes to testing. Here's an example:
/* eslint-disable camelcase */
import { Middleware, SlackShortcutMiddlewareArgs, SlackShortcut } from '@slack/bolt';
import logger from '../../logger';
import { app } from '../../app';
import getRequiredEnvVar from '../../utils/getRequiredEnvVar';
import { getPostAnonymousQuestionModalBlocks } from '../blocks/postAnonymousQuestion';
import { callbackIds } from '../constants';
export const postAnonymousQuestion: Middleware<SlackShortcutMiddlewareArgs<SlackShortcut>> = async ({
shortcut,
ack,
}) => {
ack();
try {
await app.client.views.open({
token: getRequiredEnvVar('SLACK_TOKEN'),
trigger_id: shortcut.trigger_id,
view: {
callback_id: callbackIds.postQuestionAnonymouslySubmitted,
type: 'modal',
title: {
type: 'plain_text',
text: 'Ask Question Anonymously',
},
blocks: getPostAnonymousQuestionModalBlocks(),
submit: {
type: 'plain_text',
text: 'Ask Question',
},
},
});
} catch (error) {
logger.error('Something went wrong publishing a view to Slack: ', error);
}
};
/* eslint-disable camelcase, @typescript-eslint/no-explicit-any, import/first */
import 'jest';
import supertest from 'supertest';
import { createHash } from '../utils/slack';
import logger from '../../../logger';
const signingSecret = 'Secret';
process.env.SLACK_SIGNING_SECRET = signingSecret;
import { receiver, app } from '../../../app';
import { callbackIds } from '../../../slack/constants';
const trigger_id = '1234';
const mockShortcutPayload: any = {
type: 'shortcut',
team: { id: 'XXX', domain: 'XXX' },
user: { id: 'XXX', username: 'XXX', team_id: 'XXX' },
callback_id: callbackIds.postAnonymousQuestion,
trigger_id,
};
const viewsOpenSpy = jest.spyOn(app.client.views, 'open').mockImplementation();
const loggerErrorSpy = jest.spyOn(logger, 'error').mockImplementation();
describe('ignore action listener', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('handles the shortcut and opens a modal', async () => {
const timestamp = new Date().valueOf();
const signature = createHash(mockShortcutPayload, timestamp, signingSecret);
await supertest(receiver.app)
.post('/slack/events')
.send(mockShortcutPayload)
.set({
'x-slack-signature': signature,
'x-slack-request-timestamp': timestamp,
})
.expect(200);
expect(viewsOpenSpy).toBeCalled();
const args = viewsOpenSpy.mock.calls[0][0];
expect(args.trigger_id).toEqual(trigger_id);
});
it("logs an error if the modal can't be opened", async () => {
const timestamp = new Date().valueOf();
const signature = createHash(mockShortcutPayload, timestamp, signingSecret);
viewsOpenSpy.mockRejectedValueOnce(null);
await supertest(receiver.app)
.post('/slack/events')
.send(mockShortcutPayload)
.set({
'x-slack-signature': signature,
'x-slack-request-timestamp': timestamp,
})
.expect(200);
expect(viewsOpenSpy).toBeCalled();
expect(loggerErrorSpy).toBeCalled();
});
}); Check out that project if you like the pattern above 🙂 |
👋 It looks like this issue has been open for 30 days with no activity. We'll mark this as stale for now, and wait 10 days for an update or for further comment before closing this issue out. |
Description
Hi all,
Thanks for a great framework!
It would be very useful if you could add to the documentation just a few examples of unit tests for bolt app. I suppose that writing tests is not that complicated if you have some experience, but it would be a great help for people who are new to mocking, stubbing etc.
What type of issue is this? (place an
x
in one of the[ ]
)Requirements (place an
x
in each of the[ ]
)The text was updated successfully, but these errors were encountered: