简体   繁体   English

如何 Jest spyOn 返回块中的函数

[英]How to Jest spyOn a function in a return block

I am trying to spyOn promise1 with a mock implementation (resolved promise with a result of {abc: 'efg'} . However, I am getting the error of Cannot read property 'abc' of undefined . How do I ensure that my mock implementation of promise1 is used?我正在尝试使用模拟实现来监视promise1 (解决了{abc: 'efg'}结果的承诺。但是,我收到了Cannot read property 'abc' of undefined的错误。我如何确保我的模拟实现使用promise1的?

export const test = (id) => (dispatch) => {
    // do something
    return (
        promise1(id)
            .then((result1.abc) => {
                // do something 
            })
            .then((result2) =>
                promise2(result2)
                    .then((result3) => {
                        dispatch(showNotification({type: 'success'}),
                    })
                    .catch((err) => {
                        dispatch(showNotification({type: 'timeout'}),
                        throw new Error(err);
                    })
            )
            .catch((err) => {
                dispatch(
                        dispatch(showNotification({type: 'failed'}),
                );
            })
    );
};
describe("test", () => {
    it("dispatches success notification if promise2 returns a resolved promise", async () => {

        const promise1 = jest.spyOn(api, "promise1")
        .mockImplementation(() => Promise.resolve({abc: 'efg'}))

        const showNotification = jest.spyOn(actions, 'showNotificationAction')

        await test(1)(dispatch);

        expect(showNotification).toHaveBeenCalledWith(
            {
                type: 'success',
            })
    });
})```

Here is the unit test solution:这是单元测试解决方案:

actions.ts : actions.ts

import { promise1, promise2 } from './api';

export const showNotification = (action) => {
  return {
    ...action,
    payload: {},
  };
};

export const someAction = (id) => (dispatch) => {
  return promise1(id)
    .then((result1) => {
      return result1.abc;
    })
    .then((result2) =>
      promise2(result2)
        .then((result3) => {
          dispatch(showNotification({ type: 'success' }));
        })
        .catch((err) => {
          dispatch(showNotification({ type: 'timeout' }));
          throw new Error(err);
        }),
    )
    .catch((err) => {
      dispatch(dispatch(showNotification({ type: 'failed' })));
    });
};

api.ts : api.ts :

export const promise1 = (id) => Promise.resolve({ abc: 'real abc' });
export const promise2 = (data) => Promise.resolve('real promise2 data');

actions.test.ts : actions.test.ts

import * as actions from './actions';
import * as api from './api';

describe('test', () => {
  it('dispatches success notification if promise2 returns a resolved promise', async () => {
    const promise1Spy = jest.spyOn(api, 'promise1').mockImplementation(() => Promise.resolve({ abc: 'efg' }));
    const promise2Spy = jest.spyOn(api, 'promise2').mockResolvedValueOnce('fake promise2 data');
    const showNotification = jest.spyOn(actions, 'showNotification');
    const dispatch = jest.fn();

    await actions.someAction(1)(dispatch);

    expect(promise1Spy).toBeCalledWith(1);
    expect(promise2Spy).toBeCalledWith('efg');
    expect(showNotification).toHaveBeenCalledWith({
      type: 'success',
    });
    expect(dispatch).toBeCalledWith({ type: 'success', payload: {} });
  });
});

Unit test results with coverage report:带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/59796811/actions.test.ts
  test
    ✓ dispatches success notification if promise2 returns a resolved promise (8ms)

------------|----------|----------|----------|----------|-------------------|
File        |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
------------|----------|----------|----------|----------|-------------------|
All files   |    68.75 |      100 |       60 |    76.92 |                   |
 actions.ts |       75 |      100 |       75 |    72.73 |          21,22,26 |
 api.ts     |       50 |      100 |        0 |      100 |                   |
------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        6.272s, estimated 12s

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59796811源代码: https : //github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59796811

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM