首页 > 解决方案 > 如何开玩笑地调用外部函数

问题描述

我是单元测试新手,正在尝试测试我的控制器方法。我的项目架构设计如下 Controller->Service->Model

我的测试场景:

  1. 将正确的参数传递给控制器​​方法并测试成功响应
  2. 将无效参数传递给控制器​​方法并测试错误响应

当我要测试场景 1 时,根据我的理解,我想模拟我的programService并返回值。我编写了如下测试并出现错误。

我真的很感激有人能解决这个问题

ProgramsController.js

const ProgramService = require('../../services/program/programService');

class ProgramsController {
  constructor() {
    this.programService = new ProgramService();
  }

  async subscribe(req, res) {
    try {
      const { userId, uuid, msisdn, body: { programId } } = req;
      const data = { userId, programId, msisdn, uuid }

      const subscribe = await this.programService.subscribeUser(data);
      res.json({
        status: true,
        message: 'Success',
        friendly_message: constant.MSG.SUBSCRIPTION,
        data: subscribe
      })
    } catch (error) {
      res.status(500)
        .json({
          status: false,
          message: 'Fail',
          friendly_message: constant.MSG.SUBSCRIPTION_FAIL
        })

    }
  }
}

程序服务.js

class ProgramService {

    constructor() {
        this.subscriber = new Subscriber();
        this.subsciberProgram = new SubsciberProgram()
    }

    async subscribeUser(data) {
        try {
            const { msisdn, userId, programId, uuid } = data;
                ...

            return subscribedData;

        } catch (error) {
            throw error;
        }
    }
}
module.exports = ProgramService;

test.spec.js

const ProgramsService = require('../src/services/program/programService')
const ProgramsController = require('../src/controllers/programs/programsController')
const programController = new ProgramsController()
const programsService = new ProgramsService()

beforeAll(() => {
  db.sequelize.sync({ force: true }).then(() => { });

});
const mockRequest = (userId, uuid, msisdn, body) => ({
  userId,
  uuid,
  msisdn,
  body,
});

const mockResponse = () => {
  const res = {};
  res.status = jest.fn().mockReturnValue(res);
  res.json = jest.fn().mockReturnValue(res);
  return res;
};

const serviceRecord = { userId: 1, programId: 1, msisdn: '56768382967', uuid: '46651a19-3ef1-4149-818e-9bd8a5f359ef' };
const fakeServiceReturn = { program_id: 1, amount: 5, no_of_questions: 10 }

describe('Subscribe', () => {

  test('should return 200', async () => {
    const req = mockRequest(
      1,
      '56768382967',
      '46651a19-3ef1-4149-818e-9bd8a5f359ef',
      { 'programId': 1 }
    );
    const res = mockResponse();

    const spy = jest.spyOn(programsService, 'subscribeUser').mockImplementation(() => serviceRecord);

    await programController.subscribe(req, res);
    expect(programsService.subscribeUser()).toHaveBeenCalledWith(fakeServiceReturn);

    expect(res.status).toHaveBeenCalledWith(500);
   expect(res.json).toHaveBeenCalledWith({
    status: true,
    message: 'Success',
    friendly_message: 'successfull get data',
    data : { program_id: 1, amount: 5, no_of_questions: 10 }
   });
    spy.mockRestore();
  });
});

在此处输入图像描述

我如何模拟programService.subscribeUser和测试成功响应?

标签: node.jsunit-testingjestjs

解决方案


这个模拟应该返回一个承诺:

jest.spyOn(programsService, 'subscribeUser').mockImplementation(() => Promise.resolve(serviceRecord));

推荐阅读