jest.mockImplementation()无法在构造函数()中存根方法的返回值

时间:2019-12-10 11:48:13

标签: typescript jestjs

我正尝试通过遵循本主题中评分最高的响应来对实例方法进行存根:Jest: How to mock one specific method of a class

方法.getFileName()通常应采用第3个参数并返回文件名,在这种情况下为file.js。我以为我对它进行了重写以覆盖并返回scriptTag.js

它仍然返回file.js,表示.mockImplementation()constructor()期间没有运行。

是否有任何方法可以使用间谍或存根函数覆盖在构造函数中分配的值?当我要覆盖默认的构造函数值时,在beforeEach内部实例化时,这将很有帮助。

ScriptTag.ts
  public localFileName: string;

  constructor(storeDomain: string, generalToken: string, filePath: string) {
    super(storeDomain, generalToken);
    this.localFileName = this.getFileName(this.filePath);
  }

  public getFileName(filePathOrUrl: string): string {
    const fileNameMatch: string[]|null = filePathOrUrl.match(/\/{1}(\w+.js)$/);
    if (Boolean(fileNameMatch)) { return fileNameMatch![1]; }
    else { throw Error("Filename not found"); }
  }
ScriptTag.test.ts
test("constructor()", () => {
  const scriptTag: ScriptTag = new ScriptTag("subdomain.shopify.com", 'generalTokenValue', "../path/to/file.js");
  const spy = jest
    .spyOn(scriptTag, "getFileName")
    .mockImplementation(() => "scriptTag.js");

  // expect(scriptTag.getFileName('x')).toEqual('scriptTag.js');
  expect(scriptTag.localFileName).toEqual('scriptTag.js');

});
terminal
  ✕ constructor() (10ms)

  ● constructor()

    expect(received).toEqual(expected) // deep equality

    Expected: "scriptTag.js"
    Received: "file.js"

      17 |   
      18 |   // expect(scriptTag.getFileName('x')).toEqual('scriptTag.js');
    > 19 |   expect(scriptTag.localFileName).toEqual('scriptTag.js');
         |                                   ^
      20 |   
      21 | });

      at Object.<anonymous> (functions/src/classes/__tests__/ScriptTag.test.ts:19:35)

1 个答案:

答案 0 :(得分:1)

您实例化ScriptTag类,然后localFileName属性的值已分配给file.js

实例化后,使用jest.spyOn监视getFileName方法。已经晚了。

在实例化getFileName类之前,您需要监视ScriptTag方法并为其创建存根。

例如

ScriptTag.ts

export class ScriptTag {
  localFileName = '';
  filePath = 'file.js';
  constructor(storeDomain: string, generalToken: string, filePath: string) {
    this.localFileName = this.getFileName(this.filePath);
  }

  public getFileName(filePathOrUrl: string): string {
    const fileNameMatch: string[] | null = filePathOrUrl.match(/\/{1}(\w+.js)$/);
    if (Boolean(fileNameMatch)) {
      return fileNameMatch![1];
    } else {
      throw Error('Filename not found');
    }
  }
}

ScriptTag.test.ts

import { ScriptTag } from './ScriptTag';

describe('ScriptTag', () => {
  it('should pass', () => {
    jest.spyOn(ScriptTag.prototype, 'getFileName').mockImplementation(() => 'scriptTag.js');
    const scriptTag: ScriptTag = new ScriptTag('subdomain.shopify.com', 'generalTokenValue', '../path/to/file.js');
    expect(scriptTag.localFileName).toEqual('scriptTag.js');
    expect(scriptTag.getFileName).toBeCalled();
  });
});

单元测试结果

 PASS  src/stackoverflow/59266532/ScriptTag.test.ts (10.73s)
  ScriptTag
    ✓ should pass (7ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        12.787s

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