簡體   English   中英

Jest 單元測試 + 收到未定義

[英]Jest Unit test + received undefined

我使用 Jest 作為我的單元測試框架。 我正在嘗試模擬第三方 npm“請求”並執行我的測試用例,但我正在接收並且測試失敗

expect(jest.fn()).toHaveBeenCalledWith(...expected)

    Expected: 200

    Number of calls: 0

以下是我的代碼:

規范.js

jest.mock('request', () => ({
  post: jest.fn()
}));
const request = require('request');

const mockRequest = (reqData) => {
    return {
      params: reqData.params? reqData.params:{} ,
      body: reqData.body?reqData.body:{},
      headers: reqData.headers?reqData.headers:{}
    };
  };

  const mockResponse = () => {
    const res = {};
    res.status = jest.fn().mockReturnValue(res);
    res.json = jest.fn().mockReturnValue(res);
    res.send = jest.fn().mockReturnValue(res);
    return res;
  };
  describe("Test suite for controller", () => {   
    test("should return true for successful validation",async () => {
request.post.mockResolvedValue({
        "key1":"value1",
        "key2":"value2"
      });
 const req = mockRequest();
      const res = mockResponse();
      const Ctrl = require('../../controllers/ctrl')
      await Ctrl.validate(req, res);
      //const result = await res1.json();
      expect(res.status).toHaveBeenCalledWith(200); 
});
});

控件.js

const request = require('request');
module.exports = {
  async validate(req, res) {
      var postBody = {
        url: url,
        form: body,
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      };      

      await request.post(postBody, function (error, response, body) { 
        if (error) {
           return res.status(200).json({ result: "false" });
        } else {
            return res.status(200).json({ result: "true" });
        }
     });
});
}

請分享您的想法。 預先感謝。

  1. 您不需要將awaitrequest.post的回調一起使用,只需選擇其中之一即可。 不要一起使用它們。 選擇 Promise 或 error-first Callback 來處理異步代碼。
  2. 您應該模擬request.post的實現,以便您可以在測試用例中獲取回調函數。 然后,您可以將成功的響應或錯誤傳遞給該回調,並測試回調的代碼邏輯。
  3. 您可以使用mockFn.mockReturnThis()模擬res對象的鏈式方法。

這是單元測試解決方案:

ctrl.js :

const request = require('request');

module.exports = {
  async validate(req, res) {
    var postBody = {
      url: 'url',
      form: req.body,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
    };

    request.post(postBody, function(error, response, body) {
      if (error) {
        return res.status(200).json({ result: 'false' });
      } else {
        return res.status(200).json({ result: 'true' });
      }
    });
  },
};

ctrl.spec.js :

const request = require('request');
const Ctrl = require('./ctrl');

jest.mock('request', () => ({
  post: jest.fn(),
}));

describe('Test suite for controller', () => {
  afterAll(() => {
    jest.resetAllMocks();
  });
  test('should return true for successful validation', async () => {
    request.post.mockImplementationOnce((body, callback) => {
      callback(null);
    });
    const req = { body: {} };
    const res = { status: jest.fn().mockReturnThis(), json: jest.fn() };
    await Ctrl.validate(req, res);
    expect(request.post).toBeCalledWith(
      {
        url: 'url',
        form: {},
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
      },
      expect.any(Function),
    );
    expect(res.status).toHaveBeenCalledWith(200);
    expect(res.json).toBeCalledWith({ result: 'true' });
  });

  test('should handle error for failed validation', async () => {
    const mErr = new Error('network');
    request.post.mockImplementationOnce((body, callback) => {
      callback(mErr);
    });
    const req = { body: {} };
    const res = { status: jest.fn().mockReturnThis(), json: jest.fn() };
    await Ctrl.validate(req, res);
    expect(request.post).toBeCalledWith(
      {
        url: 'url',
        form: {},
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
      },
      expect.any(Function),
    );
    expect(res.status).toHaveBeenCalledWith(200);
    expect(res.json).toBeCalledWith({ result: 'false' });
  });
});

帶有覆蓋率報告的單元測試結果:

 PASS  src/stackoverflow/64311760/ctrl.spec.js (16.499s)
  Test suite for controller
    ✓ should return true for successful validation (16ms)
    ✓ should handle error for failed validation (2ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 ctrl.js  |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        19.59s

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM