【问题标题】:Jest expected mock function to have been called开玩笑的预期模拟函数已被调用
【发布时间】:2019-10-27 23:50:20
【问题描述】:

我正在测试以下服务:

import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { extend } from 'lodash';
import { Repository } from 'typeorm';

import { DriverDTO } from './driver.dto';
import { DriverEntity } from './driver.entity';

@Injectable()
export class DriverService {
  private logger = new Logger('DriverService');
  constructor(
    @InjectRepository(DriverEntity)
    private driverRepository: Repository<DriverEntity>,
  ) { }

  async create(clientId: string, data: DriverDTO): Promise<Partial<DriverEntity>> {
    let driver = await this.driverRepository.findOne({ where: { clientId, driverId: data.driverId } });
    this.logger.log(driver);
    if (driver) {
      throw new HttpException('Driver already exists', HttpStatus.CONFLICT);
    }
    driver = this.driverRepository.create(extend({ clientId }, data));
    await this.driverRepository.save(driver);
    return { driverId: driver.driverId, createdAt: driver.createdAt };
  }
}

service.spec.ts如下:

import { Test, TestingModule } from '@nestjs/testing';

import { DriverService } from './driver.service';
import { MockType } from '../mock/mock.type';
import { plainToClass } from 'class-transformer';
import { repositoryMockFactory } from '../mock/repositoryMock.factory';
import { getRepositoryToken } from '@nestjs/typeorm';
import { DriverEntity } from './driver.entity';
import { Repository } from 'typeorm';
import { Pagination } from '../pagination/pagination';
import { HttpException, HttpStatus } from '@nestjs/common';
import { DriverDTO } from './driver.dto';

describe('DriverService', () => {
  let service: DriverService;
  let driverRepositoryMock: MockType<Repository<DriverEntity>>;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        DriverService,
        { provide: getRepositoryToken(DriverEntity), useFactory: repositoryMockFactory },
      ],
    }).compile();

    service = module.get<DriverService>(DriverService);
    driverRepositoryMock = module.get(getRepositoryToken(DriverEntity));
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
    expect(driverRepositoryMock).toBeDefined();
  });

  describe('DriverService.create()', () => {
    const driverDto: DriverDTO = {
      driverId: 'one',
    };

    const driver: DriverEntity = plainToClass(DriverEntity, {
      id: 1,
      clientId: 'one',
      driverId: 'one',
      createdAt: '2019-02-11T04:11:00.766Z',
      updatedAt: '2019-02-11T04:11:00.766Z',
    });

    it('should create driver if it does not already exist', () => {
      const response: Partial<DriverEntity> = plainToClass(DriverEntity, {
        driverId: driver.driverId,
        createdAt: driver.createdAt,
      });

      driverRepositoryMock.findOne.mockReturnValue(undefined);
      driverRepositoryMock.create.mockReturnValue(driver);
      expect(service.create('one', driverDto)).resolves.toEqual(response);
      expect(driverRepositoryMock.findOne).toHaveBeenCalledTimes(1);
      expect(driverRepositoryMock.findOne).toHaveBeenCalledWith({ where: { clientId: 'one', driverId: driverDto.driverId } });
      expect(driverRepositoryMock.create).toHaveBeenCalledTimes(1);
      expect(driverRepositoryMock.create).toHaveBeenCalledWith({
        clientId: driver.clientId,
        driverId: driver.driverId,
      });
      expect(driverRepositoryMock.save).toHaveBeenCalledWith(driver);
    });
  });
});

但我不断收到以下错误:

● DriverService › DriverService.create() › should create driver if it does not already exist

    expect(jest.fn()).toHaveBeenCalledTimes(1)

    Expected mock function to have been called one time, but it was called zero times.

      237 |       expect(driverRepositoryMock.findOne).toHaveBeenCalledTimes(1);
      238 |       expect(driverRepositoryMock.findOne).toHaveBeenCalledWith({ where: { clientId: 'one', driverId: driverDto.driverId } });
    > 239 |       expect(driverRepositoryMock.create).toHaveBeenCalledTimes(1);
          |                                           ^
      240 |       expect(driverRepositoryMock.create).toHaveBeenCalledWith({
      241 |         clientId: driver.clientId,
      242 |         driverId: driver.driverId,

      at Object.it (driver/driver.service.spec.ts:239:43)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 8 passed, 9 total
Snapshots:   0 total
Time:        1.762s, estimated 6s
Ran all test suites matching /src\/driver\/driver.service.spec.ts/i.

我像这样模拟了存储库:

import { Repository, Entity } from 'typeorm';
import { MockType } from './mock.type';

// @ts-ignore
export const repositoryMockFactory: () => MockType<Repository<any>> = jest.fn(() => ({
    findOne: jest.fn(entity => entity),
    findAndCount: jest.fn(entity => entity),
    create: jest.fn(entity => entity),
    save: jest.fn(entity => entity),
}));

我似乎找不到原因。任何帮助将不胜感激。

【问题讨论】:

    标签: javascript node.js typescript jestjs nestjs


    【解决方案1】:

    让你的测试函数异步等待直到你的服务方法完全执行,然后再检查你的模拟期望:

    it('should create driver if it does not already exist', async () => {
      //                                                    ^^^^^
      // ...
      await expect(service.create('one', driverDto)).resolves.toEqual(response);
    //^^^^^
    

    【讨论】:

    • 如何模拟 Repository.createQueryBuilder().something().something().execute()。基本上是用笑话链接函数?
    猜你喜欢
    • 1970-01-01
    • 2018-12-27
    • 2019-03-23
    • 1970-01-01
    • 2019-11-19
    • 1970-01-01
    • 2019-03-28
    • 2018-08-17
    • 1970-01-01
    相关资源
    最近更新 更多