javascriptunit-testingjestjstddsendbird

Trying to learn how to write tests, how do I write when I have a promise?


I created a function that connects to an API and returns a promise.. I wanted to test that function so created a mock function in Jest to handle it, however I am not really sure I am doing this right and I am finding it very hard to find good resources on how to go about writing good unit tests..

export const sbConnect = (userId) => {
  return new Promise((resolve, reject) => {
    const sb = new SendBird({appId: APP_ID});
    sb.connect(userId, API_Token, (user, error) => {
      if (error) {
        reject(error);
      } else {
        resolve(user);
      }
    });
  });
};

This is the function I am trying to test. I have created a test and tried this so far..

import {sbConnect} from '../helpers/sendBirdSetupActions';

const SendBird = jest.fn();

describe('Connects to SendBird API', () => {
  it('Creates a new SB instance', () => {
    let userId = 'testUser';
    let APP_ID = 'Testing_App_ID_001';
    sbConnect(userId);
    expect(SendBird).toBeCalled();
  });
});

Solution

  • You can use jest.mock(moduleName, factory, options) to mock sendbird module manually.

    Mock SendBird constructor, instance, and its methods.

    E.g.

    index.ts:

    import SendBird from 'sendbird';
    
    const API_Token = 'test api token';
    const APP_ID = 'test api id';
    
    export const sbConnect = (userId) => {
      return new Promise((resolve, reject) => {
        const sb = new SendBird({ appId: APP_ID });
        sb.connect(userId, API_Token, (user, error) => {
          if (error) {
            reject(error);
          } else {
            resolve(user);
          }
        });
      });
    };
    

    index.test.ts:

    import { sbConnect } from './';
    import SendBird from 'sendbird';
    
    const mSendBirdInstance = {
      connect: jest.fn(),
    };
    jest.mock('sendbird', () => {
      return jest.fn(() => mSendBirdInstance);
    });
    
    describe('65220363', () => {
      afterAll(() => {
        jest.resetAllMocks();
      });
      it('should get user', async () => {
        const mUser = { name: 'teresa teng' };
        mSendBirdInstance.connect.mockImplementationOnce((userId, API_Token, callback) => {
          callback(mUser, null);
        });
        const actual = await sbConnect('1');
        expect(actual).toEqual(mUser);
        expect(SendBird).toBeCalledWith({ appId: 'test api id' });
        expect(mSendBirdInstance.connect).toBeCalledWith('1', 'test api token', expect.any(Function));
      });
    
      it('should handle error', async () => {
        const mError = new Error('network');
        mSendBirdInstance.connect.mockImplementationOnce((userId, API_Token, callback) => {
          callback(null, mError);
        });
        await expect(sbConnect('1')).rejects.toThrow(mError);
        expect(SendBird).toBeCalledWith({ appId: 'test api id' });
        expect(mSendBirdInstance.connect).toBeCalledWith('1', 'test api token', expect.any(Function));
      });
    });
    

    unit test result:

     PASS  src/stackoverflow/65220363/index.test.ts (11.115s)
      65220363
        ✓ should get user (6ms)
        ✓ should get user (3ms)
    
    ----------|----------|----------|----------|----------|-------------------|
    File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    ----------|----------|----------|----------|----------|-------------------|
    All files |      100 |      100 |      100 |      100 |                   |
     index.ts |      100 |      100 |      100 |      100 |                   |
    ----------|----------|----------|----------|----------|-------------------|
    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        12.736s
    

    source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/65220363