如何jest.spyOn构造函数中调用的示例方法

5us2dqdw  于 2022-12-08  发布在  Jest
关注(0)|答案(1)|浏览(220)

Simplified problem case:

export class MyClass {

    constructor() {
        this.myMethod();
    }

    myMethod() {
        console.log(42);
    }

}

Testing the constructor:

describe('CLASS: MyClass', () => {
    let sut: MyClass;

    beforeEach(() => {
        jest.clearAllMocks();
        sut = new MyClass();
    });

    describe('CONSTRUCTOR', () => {
    
        test('should construct correctly and call myMethod', () => {
            const spy = jest.spyOn(sut, 'myMethod').mockImplementationOnce(jest.fn());
    
            expect(sut).toBeTruthy();
            expect(spy).toHaveBeenCalled();
        });    
    });
});

Of course this doesn't work, as the spy is initiated after sut is constructed, so it can't register the call.
Neither is it possible to initiate the spy before sut, as it can't spy on something that doesn't exist yet.
Nor did I have success trying to spy on MyClass.prototype.
Sure, I could spy on the implementation details of myMethod (basically jest.spyOn(console, 'log'). But that defies the separation of units for testing.
It's probably trivial, but what am I missing, how to get this very simple test to work?

xqk2d5yq

xqk2d5yq1#

您应该监视MyClass,而不是示例化的类sut
你仍然可以在不嘲笑实现的情况下监视方法,但是在这里最好避免执行其中的代码并在控制台中记录42。

describe('CLASS: MyClass', () => {
  let sut: MyClass
  let spy: jest.SpyInstance = jest.spyOn(MyClass.prototype, 'myMethod')

  beforeEach(() => {
    jest.clearAllMocks()
    spy.mockImplementationOnce(jest.fn())
    sut = new MyClass()
  })

  describe('CONSTRUCTOR', () => {
    test('should construct correctly and call myMethod', () => {
      expect(sut).toBeTruthy()
      expect(spy).toHaveBeenCalled()
      expect(spy).toHaveBeenCalledTimes(1)
    })
  })
})

相关问题