首页 > 解决方案 > 用玩笑模拟 post 方法 npm 请求模块

问题描述

我知道现在不推荐使用npm 请求模块,但我想用 jest 模拟一个 post http 调用。

这是我的功能

import { post } from 'request'; 

export functionToFetch(uriFetching) {

    return post(
        {
            url: uriFetching,
            headers: {},
            json,
        },

        (error, response, body) => {

            if (error) {
                console.log('error)
                // return specific code
            }
              // return success code

            
        }

}

在我的测试中尝试这个:

import { post } from 'request';
import {functionToFetch} from './example';

it('should do some specific handling on error', () => {
    const fakeURI = 'http://example.com'
    
    request.post = jest.fn().mockImplementation(() => Promise.resolve(new Response('test')));

    // on error
    expect(functionToFetch(fakeURI).toEqual(expected);
    // on success
    expect(functionToFetch(fakeURI).toEqual(expected2);

});

但它返回 TypeError: Cannot set property 'post' of undefined

我想模拟该方法来处理错误并响应其中的测试方法

标签: javascriptunit-testingtestingjestjsfetch

解决方案


使用jest.mock()并将post.mockImplementation()执行此操作。post您可以在测试用例中获取传入函数的实际回调函数。并使用模拟参数手动执行它。

例如

index.js

import { post } from 'request';

export function functionToFetch(uriFetching) {
  const json = {};

  post({ url: uriFetching, headers: {}, json }, (error, response, body) => {
    if (error) {
      console.log(error);
    } else {
      console.log(response);
    }
  });
}

index.test.js

import { functionToFetch } from '.';
import { post } from 'request';

jest.mock('request');

describe('67210149', () => {
  afterAll(() => {
    jest.resetAllMocks();
  });
  it('should do some specific handling on error', () => {
    const mError = new Error('network');
    post.mockImplementation((option, callback) => {
      callback(mError);
    });
    const logSpy = jest.spyOn(console, 'log');
    const fakeURI = 'http://example.com';
    functionToFetch(fakeURI);
    expect(logSpy).toBeCalledWith(mError);
    expect(post).toBeCalledWith({ url: 'http://example.com', headers: {}, json: {} }, expect.any(Function));
  });
});

单元测试结果:

 PASS  examples/67210149/index.test.js (7.274 s)
  67210149
    ✓ should do some specific handling on error (24 ms)

  console.log
    Error: network
        at Object.<anonymous> (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/examples/67210149/index.test.js:8:20)
        at Object.asyncJestTest (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:106:37)
        at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:45:12
        at new Promise (<anonymous>)
        at mapper (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:28:19)
        at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:75:41
        at processTicksAndRejections (internal/process/task_queues.js:93:5)

      at console.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        7.836 s, estimated 8 s

推荐阅读