【问题标题】:How to mock the return value of a function that is defined in the same class that is being used by the tested service如何模拟在被测试服务使用的同一类中定义的函数的返回值
【发布时间】:2021-08-13 07:00:54
【问题描述】:

我在我的应用程序中使用 Feathers.js。我有一个eta 服务,它使用Eta 类作为它的控制器。我的目标是测试服务,而不是类,特别是 .find() 方法。 .find() 方法正在使用另一个私有方法 getEta()。后者调用googleMapsClient.distancematrix()

googleMapsClient 被定义为类的属性。

export class Eta implements Partial<ServiceMethods<LocationInformation>> {
  app: Application;
  options: ServiceOptions;
  googleMapsClient: any;

  MAX_TIME_BEFORE_LOCATION_STALE_MINS = 90;

  constructor(options: ServiceOptions = {}, app: Application) {
    this.options = options;
    this.app = app;
    this.googleMapsClient = new Client({});
  }

  getStaleThreshold = (): string => {
    return moment()
      .subtract(this.MAX_TIME_BEFORE_LOCATION_STALE_MINS, 'minutes')
      .toISOString();
  };

  getEta = async (
    latitude: number,
    longitude: number,
    meetupLocation: { latitude: number; longitude: number },
  ): Promise<number> => {
    try {
      const matrix = await this.googleMapsClient.distancematrix({
        params: {
          origins: [{ lat: latitude, lng: longitude }],
          destinations: [
            { lat: meetupLocation.latitude, lng: meetupLocation.longitude },
          ],
          mode: 'driving',
          units: 'imperial',
          departure_time: 'now',
          traffic_model: 'best_guess',
          key: process.env.GOOGLE_MAPS,
        },
        timeout: 3000,
      });

      const { value } = matrix.data.rows[0].elements[0].duration;
      // eta given in seconds
      return value;
    } catch (error) {
      throw new GeneralError(error);
    }
  };

  async find(params: Params): Promise<any> {
    const longitude = params.query ? params.query?.longitude : null;
    const latitude = params.query ? params.query?.latitude : null;
    const type = params.query ? params.query?.type : null;
    const connectionID = params.query ? params.query?.connectionID : null;
    const connectionService = this.app.service('connection');
    const connection: any = await connectionService.get(connectionID);
    const { vehicleID, pickupLocation, dropoffLocation, dropoffTime, pickupTime, status } = connection;
    let result: LocationInformation | {} = {};

    switch (status) {
      case 'COMPLETE':
        if (type === USER_TO_HANDOFF) {
          const etaSeconds = await this.getEta(
            latitude,
            longitude,
            pickupLocation,
          );
          result =  {
            etaSeconds,
            latitude,
            longitude,
          };
        }
        break;
      default:
        break;
    }
    return result;
  }
}

我想测试 Eta 查找服务方法,为此我需要模拟 getEta。我不需要测试是否调用了getEta。我只需要模拟它的返回值并测试.find() 方法。

这是我目前尝试过的

import { Eta } from '../../src/services/eta/eta.class';

describe("'eta' service", () => {
 // ...omitted for brewety

 it('getting ETA for the driver', async () => {
    const data = { 
      longitude: -122.434944, 
      latitude: 37.7599487, 
      type: 'USER_TO_HANDOFF', 
      connectionID: confirmedConnection.id 
    };
    const getEtaMock = jest.fn(async () => Promise.resolve(74));
    const oldGetEta = Eta.prototype.getEta;
    Eta.prototype.getEta = getEtaMock;

    const etaData = await app.service('eta').find({
      query: {
        ...data,
      },
    });
    expect(etaData).toBeTruthy();
    Eta.prototype.getEta = oldGetEta;
  });
});

这似乎不起作用并产生NotFound at connection get,尽管在没有模拟时它确实获得了连接。有没有办法模拟getEta 的返回值以测试app.servcie('eta').find 调用?

【问题讨论】:

    标签: typescript unit-testing jestjs mocking feathersjs


    【解决方案1】:

    我也在为同样的问题而苦苦挣扎。试试这个:

    const app = require('./src/app'); // entry point to your feathers app
    
    describe("'eta' service", () => {
     // ...omitted for brewety
    
     it('getting ETA for the driver', async () => {
        const data = { 
          longitude: -122.434944, 
          latitude: 37.7599487, 
          type: 'USER_TO_HANDOFF', 
          connectionID: confirmedConnection.id 
        };
    
        app.service('eta').getEta = jest.fn();
        app.service('eta').getEta.mockReturnValue(74);
    
        const etaData = await app.service('eta').find({
          query: {
            ...data,
          },
        });
        expect(etaData).toBeTruthy();
    
      });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-21
      • 2018-12-28
      • 2023-03-12
      • 2018-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多