首页 > 解决方案 > 如何嘲笑开玩笑的承诺

问题描述

我是开玩笑的新手,我一直在尝试模拟以下功能。我有模拟,但它们似乎不起作用。我可以嘲笑JSON.parse,这很容易。我应该采取什么方法来嘲笑getConfigrp

我的index.ts

import rp from "request-promise-native";
import { ConfigService } from "my-config-service";

export default class MyService {

  public static async getMyToken(myAccountIdhere?: string) {

    const { ThisSecretString } = await ConfigService.getConfig('my-token-credentials');
    const { ThisclientId, ThisclientSecret } = JSON.parse(ThisSecretString);

    const params = {
      headers: {
        "This-Client-Id": ThisclientId,
        "This-Client-Secret": ThisclientSecret,
      },
      url: `${token_URI}/${myAccountIdhere}`,
      'content-type': 'application/json',
      'accept':  'application/json'
    };

    return rp(params);
  }
}

我试图模拟getConfig如下:

jest.mock("../src/asmConfigService", () =>{
  return {
    getConfig : mgetConfig
  }
});

const mgetConfig = jest.fn().mockImplementation(() => {
  return {
    SecretString: "mySecretString"
  }
});

标签: unit-testingmockingjestjs

解决方案


这是单元测试解决方案:

myService.ts

import rp from 'request-promise-native';
import { ConfigService } from './asmConfigService';

const token_URI = 'https://example.com';

export default class MyService {
  public static async getMyToken(myAccountIdhere?: string) {
    const { ThisSecretString } = await ConfigService.getConfig('my-token-credentials');
    const { ThisclientId, ThisclientSecret } = JSON.parse(ThisSecretString);

    const params = {
      headers: {
        'This-Client-Id': ThisclientId,
        'This-Client-Secret': ThisclientSecret,
      },
      url: `${token_URI}/${myAccountIdhere}`,
      'content-type': 'application/json',
      accept: 'application/json',
    };
    return rp(params);
  }
}

asmConfigService.ts

export class ConfigService {
  public static async getConfig(token) {
    return {
      ThisSecretString: JSON.stringify({
        ThisclientId: 'real id',
        ThisclientSecret: 'real secret',
      }),
    };
  }
}

myService.test.ts

import MyService from './myService';
import { ConfigService } from './asmConfigService';
import rp from 'request-promise-native';

jest.mock('./asmConfigService.ts', () => {
  const mConfigService = {
    getConfig: jest.fn(),
  };
  return { ConfigService: mConfigService };
});
jest.mock('request-promise-native', () => {
  return jest.fn();
});

describe('MyService', () => {
  afterEach(() => {
    jest.restoreAllMocks();
    jest.resetAllMocks();
  });
  it('#getMyToken', async () => {
    const mConfig = {
      ThisSecretString: JSON.stringify({
        ThisclientId: 'fake id',
        ThisclientSecret: 'fake secret',
      }),
    };
    (ConfigService.getConfig as jest.Mocked<any>).mockResolvedValueOnce(mConfig);
    const jsonParseSpy = jest.spyOn(JSON, 'parse');
    const actual = await MyService.getMyToken('1');
    expect(actual).toBeUndefined();
    expect(jsonParseSpy).toBeCalledWith(mConfig.ThisSecretString);
    expect(rp).toBeCalledWith({
      headers: {
        'This-Client-Id': 'fake id',
        'This-Client-Secret': 'fake secret',
      },
      url: `https://example.com/1`,
      'content-type': 'application/json',
      accept: 'application/json',
    });
  });
});

覆盖率 100% 的单元测试结果:

 PASS  src/stackoverflow/59187875/myService.test.ts
  MyService
    ✓ #getMyToken (11ms)

--------------|----------|----------|----------|----------|-------------------|
File          |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------|----------|----------|----------|----------|-------------------|
All files     |      100 |      100 |      100 |      100 |                   |
 myService.ts |      100 |      100 |      100 |      100 |                   |
--------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.35s, estimated 8s

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


推荐阅读