0
votes

Trying to create a test case for the following function. Not familiar with async and await, using Jest and Enzyme for React Js. Goal: test to pass properly And make sure the function is getting called correctly

  async patchPolicy() {
    const { user, services } = this.props;
    const { data } = this.state;
    const body = {
      Policies: [
        {
          Choices: data.Choices || ''
        }
      ]
    };
    PolicyModels.patchWork({
      user,
      services,
      body,
      id: this.state.Policy
    });
    const contextBody = data.WORK_CONTEXT[0];
    const Context_UID = '';
    const method = 'POST';
    if (contextBody) {
      //
      if (contextBody.Context_UID) {
        // If has UID, Patch
        PolicyModels.patchWorkContext({
          user,
          services,
          body: contextBody,
          id: contextBody.Context_UID
        });
      } else {
        contextBody.WorkID = this.state.data.WorkID;
        PolicyModels.patchWorkContext({
          user,
          services,
          body: contextBody,
          id: contextBody.Context_UID
        });
      }
    }
  }

Created the following test for it but I keep getting this message:

expect(jest.fn()).toHaveBeenCalled() Expected mock function to have been called.

const patchWorkMock = jest.fn();
PolicyModels.patchWorkContext = patchWorkMock;

beforeEach(() => {
  wrapper = mount(
    <MemoryRouter keyLength={0}>
      <EditPolicy {...baseProps} />
    </MemoryRouter>
  );
});

it('Test patchPolicy function', async () => {
  wrapper.setProps({
    services: {},
    user: {}
  });
  wrapper.find('EditPolicy').setState({
    data: {
      Policy: {},
      Description: {},
      Help_UID: {},
      Choices: {},
      WorkID: [],
      WORK_CONTEXT: []
    }
  });
  wrapper.update();
  wrapper
    .find('EditPolicy')
    .instance()
    .patchPolicy();
  expect(patchWorkMock).toHaveBeenCalled();
  return wrapper
    .find('EditPolicy')
    .instance()
    .patchPolicy()
    .then(result => {
      expect(result).toBeUndefined();
    });
});

Expect the function to get called/ and works properly . I was able to get the test to pass but i believe it did not add anything into its coverage.

2

2 Answers

0
votes

Here is the solution:

index.tsx:

import React, { Component } from 'react';
import * as PolicyModels from './PolicyModels';

export interface IEditPolicyProps {
  user: any;
  services: any[];
}

interface IEditPolicyState {
  data: {
    WorkID: string;
    Choices: string;
    WORK_CONTEXT: any[];
  };
  Policy: string;
}

export class EditPolicy extends Component<IEditPolicyProps, IEditPolicyState> {
  constructor(props: IEditPolicyProps) {
    super(props);
    this.state = {
      data: {
        WorkID: '',
        Choices: '',
        WORK_CONTEXT: []
      },
      Policy: ''
    };
  }

  public async patchPolicy() {
    const { user, services } = this.props;
    const { data } = this.state;
    const body = {
      Policies: [
        {
          Choices: data.Choices || ''
        }
      ]
    };
    PolicyModels.patchWork({
      user,
      services,
      body,
      id: this.state.Policy
    });
    const contextBody = data.WORK_CONTEXT[0];
    const Context_UID = '';
    const method = 'POST';
    if (contextBody) {
      //
      if (contextBody.Context_UID) {
        // If has UID, Patch
        PolicyModels.patchWorkContext({
          user,
          services,
          body: contextBody,
          id: contextBody.Context_UID
        });
      } else {
        contextBody.WorkID = this.state.data.WorkID;
        PolicyModels.patchWorkContext({
          user,
          services,
          body: contextBody,
          id: contextBody.Context_UID
        });
      }
    }
  }

  public render() {
    return <div>Expected mock function to have been called -Async</div>;
  }
}

PolicyModels.ts:

export function patchWork(...args) {}

export function patchWorkContext(...args) {}

index.spec.tsx:

import React from 'react';
import { ReactWrapper, mount } from 'enzyme';
import { MemoryRouter } from 'react-router';
import { EditPolicy, IEditPolicyProps } from './';
import * as PolicyModels from './PolicyModels';

describe('EditPolicy', () => {
  let wrapper: ReactWrapper;
  const baseProps: IEditPolicyProps = {
    user: {},
    services: []
  };
  beforeEach(() => {
    wrapper = mount(
      <MemoryRouter keyLength={0}>
        <EditPolicy {...baseProps} />
      </MemoryRouter>
    );
  });

  afterEach(() => {
    jest.restoreAllMocks();
  });

  it('Test patchPolicy function with context body', async () => {
    const patchWorkContextSpy = jest.spyOn(PolicyModels, 'patchWorkContext');
    wrapper.find('EditPolicy').setState({
      data: {
        Policy: '',
        Choices: '',
        WorkID: '',
        WORK_CONTEXT: [{ Context_UID: 1 }]
      }
    });
    await (wrapper.find('EditPolicy').instance() as any).patchPolicy();
    expect(patchWorkContextSpy).toBeCalledWith({ user: {}, services: [], body: { Context_UID: 1 }, id: 1 });
  });

  it('Test patchPolicy function without context body', async () => {
    const patchWorkContextSpy = jest.spyOn(PolicyModels, 'patchWorkContext');
    wrapper.find('EditPolicy').setState({
      data: {
        Policy: '',
        Choices: '',
        WorkID: '222',
        WORK_CONTEXT: [{ Context_UID: 0, WorkID: 0 }]
      }
    });
    await (wrapper.find('EditPolicy').instance() as any).patchPolicy();
    expect(patchWorkContextSpy).toBeCalledWith({
      user: {},
      services: [],
      body: { Context_UID: 0, WorkID: '222' },
      id: 0
    });
  });
});

Unit test result with coverage report:

 PASS  src/stackoverflow/56238887/index.spec.tsx (12.167s)
  EditPolicy
    ✓ Test patchPolicy function with context body (60ms)
    ✓ Test patchPolicy function without context body (4ms)

-----------------|----------|----------|----------|----------|-------------------|
File             |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------------|----------|----------|----------|----------|-------------------|
All files        |      100 |     87.5 |      100 |      100 |                   |
 PolicyModels.ts |      100 |      100 |      100 |      100 |                   |
 index.tsx       |      100 |     87.5 |      100 |      100 |                50 |
-----------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        14.746s

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/56238887

0
votes

You forgot to add the await before every call to patchPolicy :

await wrapper
    .find('EditPolicy')
    .instance()
    .patchPolicy();

By the way, a good practice to know if the test is checking every expect is to add expect.assertions in the first line of the test. For instance, in your case, if you use expect.assertions(2), your test would fail.