如何使用Jest模拟来自打字稿测试控制器的服务响应

时间:2019-12-08 13:00:36

标签: node.js typescript unit-testing jestjs

我正在测试使用Jest用打字稿编写的控制器。我尝试模拟该服务的响应,但无法解决问题。

这是我的EmployeesController

import { EmployeesService } from '../services/employeeService';
import { IDBConnection } from '../config/IDBConnection';

export class EmployeesController {
  private employeeService: EmployeesService;

  constructor(dbConnection: IDBConnection) {
    this.employeeService = new EmployeesService(dbConnection);
  }
  public async findAllEmployees(req: any, res: any) {
    const numPerPage = +req.query.pagesize;
    const page = +req.query.page;
    try {
      const count = await this.employeeService.findCount();
      const results = await this.employeeService.findAll(numPerPage, page);
      let totalEmployee = count[0].totalCount;
      if (totalEmployee === 0) {
        return res.status(404).json({
          success: false,
          message: 'Employee not found'
        });
      } else if (count && results) {
        return res.status(200).json({
          employees: results,
          maxEmployees: totalEmployee
        });
      };
    } catch {
      res.status(500).json({
        success: false,
        message: 'Server error'
      });
    };
  }

这是我的EmployeesService

import { IDBConnection } from '../config/IDBConnection';
export class EmployeesService {
  private connection: any;

  constructor(connection: IDBConnection) {
    this.connection = connection;
  }
  async findCount() {
    const results = await this.connection.execute('SELECT count(*) as totalCount FROM EmployeeDB.Employees');
    return results; // [ RowDataPacket { totalCount: 5 } ]
  }
}

我可以假设我在测试中从服务中错误地对其进行了管道传输,但是我不太确定。有人可以帮助我吗?

这是我的Employee.test

jest.mock('../../../services/employeeService');

import { EmployeesController } from '../../../controllers/employeeController';
import { EmployeesService } from '../../../services/employeeService';

describe('Employees', () => {
   test('should get count of employees', async () => {
      const getCount = jest.spyOn(EmployeesService.prototype, "findCount")
         .mockImplementation(() => Promise.resolve([{totalCount: 5}]));
      const mockResp = () => {
         const res: any = {}
         res.status = jest.fn().mockReturnValue(res)
         res.json = jest.fn().mockReturnValue(res)
         return res
      }
      const mockReq = () => {
         const req: any = {}
         req.query = jest.fn().mockReturnValue(req);
         return req
      }
      const req = mockReq({
         pagesize: 1,
         page: 0
      });
      const res = mockResp();
      await EmployeesController.prototype.findAllEmployees(req, res);
      expect(getCount).toHaveBeenCalledTimes(1); // Received number of calls: 0
   }
}

1 个答案:

答案 0 :(得分:0)

这是单元测试解决方案:

table

table.drop('movie_title', axis=1, inplace=True)

controllers/employeeController.ts

import { EmployeesService } from '../services/employeeService';
import { IDBConnection } from '../config/IDBConnection';

export class EmployeesController {
  private employeeService: EmployeesService;

  constructor(dbConnection: IDBConnection) {
    this.employeeService = new EmployeesService(dbConnection);
  }
  public async findAllEmployees(req: any, res: any) {
    const numPerPage = +req.query.pagesize;
    const page = +req.query.page;
    try {
      const count = await this.employeeService.findCount();
      const results = await this.employeeService.findAll(numPerPage, page);
      let totalEmployee = count[0].totalCount;
      if (totalEmployee === 0) {
        return res.status(404).json({
          success: false,
          message: 'Employee not found',
        });
      } else if (count && results) {
        return res.status(200).json({
          employees: results,
          maxEmployees: totalEmployee,
        });
      }
    } catch {
      res.status(500).json({
        success: false,
        message: 'Server error',
      });
    }
  }
}

services/employeeService.ts

import { IDBConnection } from '../config/IDBConnection';

export class EmployeesService {
  private connection: any;

  constructor(connection: IDBConnection) {
    this.connection = connection;
  }
  async findCount() {
    const results = await this.connection.execute('SELECT count(*) as totalCount FROM EmployeeDB.Employees');
    return results; // [ RowDataPacket { totalCount: 5 } ]
  }
  async findAll(numPerPage, page) {
    return [];
  }
}

config/IDBConnection.ts

export interface IDBConnection {}

带有覆盖率报告的单元测试结果:

Employee.test.ts

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