question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Adding unit tests examples to the documentation

See original GitHub issue

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 [ ])

  • bug
  • enhancement (feature request)
  • question
  • documentation related
  • testing related
  • discussion

Requirements (place an x in each of the [ ])

  • I’ve read and understood the Contributing guidelines and have done my best effort to follow them.
  • I’ve read and agree to the Code of Conduct.
  • I’ve searched for any related issues and avoided creating a duplicate issue.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:20
  • Comments:9 (2 by maintainers)

github_iconTop GitHub Comments

6reactions
SpencerKaisercommented, Oct 7, 2020

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:

postAnonymousQuestion.ts (Functionality to test)

/* 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);
  }
};

postQuestionAnonymously.test.ts (Tests to cover above functionality)

/* 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 🙂

4reactions
szymon-szymcommented, May 24, 2020

@RayBB a simple flow which works for me:

  • use a named functions in the listeners
  • call those functions in tests with a specific input
  • spy on mocked app web client and check args it was called with
  • match those args with a jest snapshot if needed

I can attach some code snippets if they may be useful

But for sure using the tool mentioned by seratch would be more straightforward

Read more comments on GitHub >

github_iconTop Results From Across the Web

Documentation unit tests - Medium
Example test run showing classes that are missing their documentation ... Adding unit tests to your documentation in this way faces an ...
Read more >
Unit Testing Tutorial – What is, Types & Test Example - Guru99
The purpose is to validate that each unit of the software code performs as expected. Unit Testing is done during the development (coding ......
Read more >
Best practice guide for documenting unit tests?
Carefully name tests reflecting requirement in the form of input data & expected result. I have been in similar situation but for ...
Read more >
unittest — Unit testing framework — Python 3.11.1 ...
Third-party unittest framework with a lighter-weight syntax for writing tests. For example, assert func(10) == 42 . The Python Testing Tools Taxonomy.
Read more >
Best practices for writing unit tests - .NET - Microsoft Learn
Learn best practices for writing unit tests that drive code quality and resilience for .NET Core and .NET Standard projects.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found