如何监视类构造器的玩笑?

Jon*_*Tse 6 javascript unit-testing jestjs

export class Foo {
    public static bar() {
        doSomething();
    }

    constructor(paramA, paramB) {

    } 
}
Run Code Online (Sandbox Code Playgroud)

对于类中的方法,我们可以 jest.spyOn(Foo, 'bar')用来监视该方法。构造函数呢?我们如何监视对象的实例化?

小智 11

@gillyb 是对的,只是忘了“模拟” Foo 模块

// Foo.js
export class Foo {
    public static bar() {
        doSomething();
    }

    constructor(paramA, paramB) {

    } 
}

// Foo.spec.js
import Foo from './Foo.js';
jest.mock('./Foo.js');

it('test something...', () => {
    // Assuming we did something that called our constructor
    expect(Foo).toHaveBeenCalledTimes(1);
});
Run Code Online (Sandbox Code Playgroud)

  • 通过使用“jest.mock”,您可以用模拟覆盖整个类。但是是否还有一种方法可以只监视构造函数而不覆盖类呢?这样班级就可以像往常一样工作,但会被开玩笑监视吗?因为在我的用例中,我需要该类照常工作,但我不想总是检查属性是否设置正确,以便检查是否使用正确的参数调用它。因此,如果我能够检查构造函数是否被正确调用,那就太酷了。 (3认同)

Fom*_*tia 7

如果你真的想监视构造函数,你可以这样做:

// MyClass.js

export class MyClass {
  constructor() {
    console.log("constructing");
  }
}

// MyClass.test.js

import * as MyClassModule from './MyClass';

const MyClass = MyClassModule.MyClass;

test('the constructor is called', () => {
  const constructorSpy = jest.spyOn(MyClassModule, 'MyClass');
  new MyClass();
  expect(constructorSpy).toHaveBeenCalledTimes(1);
});
Run Code Online (Sandbox Code Playgroud)

  • 如果使用“导出默认值”,这应该有效吗? (6认同)
  • 无法使用 `"babel-jest": "^27.4.4", "jest": "^27.4.3"` 预期调用次数:1 收到调用次数:0 (4认同)
  • 这应该是公认的答案。 (2认同)

Pos*_*sva 5

我认为没有官方的方法。这是我个人的做法:

const spy = jest.fn()
function Mock (...args) {
  spy(...args)
  Constructor.apply(this, args)
}
Mock.prototype = Constructor.prototype
Run Code Online (Sandbox Code Playgroud)

然后我可以检查间谍:

expect(spy).toHaveBeenCalledWith('firstArg', 'secondArg')
Run Code Online (Sandbox Code Playgroud)

  • 我真的希望这个答案有完整的例子。什么是构造函数? (7认同)
  • 在这个例子中,`Constructor` 是 `Foo` 吗? (2认同)
  • 非常糟糕的例子 (2认同)

gil*_*lyb -1

实际上有一种方法:)
甚至在官方文档中: https: //jestjs.io/docs/en/es6-class-mocks#complete-example

以下是您使用代码执行此操作的方法:

// Foo.js
export class Foo {
    public static bar() {
        doSomething();
    }

    constructor(paramA, paramB) {

    } 
}

// Foo.spec.js
import Foo from './Foo.js';

it('test something...', () => {
    // Assuming we did something that called our constructor
    expect(Foo).toHaveBeenCalledTimes(1);
});
Run Code Online (Sandbox Code Playgroud)

  • 这样做你会收到一个错误:“值必须是模拟函数或间谍”。 (17认同)