模拟第三方方法+玩笑

时间:2020-08-05 07:57:33

标签: node.js unit-testing jestjs

我正在使用jest进行后端单元测试。我需要使用它来模拟第三方库模块方法。我尝试了以下代码:

我的控制器文件:

    const edgejs = require('apigee-edge-js');
    const apigeeEdge = edgejs.edge;
   async get(req, res) {
    const abc= await apigeeEdge.connect(connectOptions);
    const Details = await abc.developers.get(options);
    return res.status(200).send(Details);
  }

test.spec.js

    let edgejs = require('apigee-edge-js');
    const ctrl = require('../../controller');
    describe("Test suite for abc", () => {
        test("should return ...", async() =>{        
            edgejs.edge = jest.fn().mockImplementationOnce(async () => 
            {return  {"connect":{"developers":{"get":[{}]}}}}
           );
         ctrl.get(req, res)    
    });

但不是嘲笑,而是调用实际的库connect方法。我在这里做错了。请分享您的想法。预先感谢。

工作代码

jest.mock('apigee-edge-js', () => {
    return { edge: { connect: jest.fn() } };
  });

    const edgejs = require('apigee-edge-js');
    test("should return ...", async () => {
        edgejs.edge.connect.mockImplementationOnce(() => Promise.resolve(
            {"developers":{"get":[{}]}}
          ));    
        edgejs.edge.connect()
        expect(edgejs.edge.connect).toBeCalled();
        
      })

错误代码:

jest.mock('apigee-edge-js', () => {
    return { edge: { connect: jest.fn() } };
  });

const Ctrl = require('../../controllers/controller'); ----> Extra line
const edgejs = require('apigee-edge-js');

test("should return ...", async () => {
    edgejs.edge.connect.mockImplementationOnce(() => Promise.resolve(
        {"developers":{"get":[{}]}}
      ));
    const req = mockRequest();
     const res = mockResponse();
    await Ctrl.get(req, res)  ---> Extra line
    expect(edgejs.edge.connect).toBeCalled();       
    
  });

Receceivig错误:TypeError:edgejs.edge.connect.mockImplementationOnce不是函数

1 个答案:

答案 0 :(得分:0)

该模拟不会产生任何影响,因为controller在导入edgejs.edge之后立即取消引用apigeeEdge = edgejs.edge。如果它使用的是edgejs.edge.connect而不是apigeeEdge.connect,则将有所不同。

不应将方法模拟为... = jest.fn(),因为这会阻止方法的恢复,并可能影响之后的其他测试;这就是jest.spyOn的目的。此外,edge是对象而不是方法。

Jest提供了模块模拟功能。第三方库通常需要在单元测试中进行模拟。

应该是:

jest.mock('apigee-edge-js', () => {
  return { edge: { connect: jest.fn() } };
});

const ctrl = require('../../controller');
const edgejs = require('apigee-edge-js');

test("should return ...", async () => {
  edgejs.edge.connect.mockImplementationOnce(() => Promise.resolve(
    {"developers":{"get":[{}]}}
  ));
  await ctrl.get(req, res)
  ...
});