【问题标题】:Jest createSpyObj开玩笑 createSpyObj
【发布时间】:2021-03-04 17:56:23
【问题描述】:

使用 Chai,您可以按如下方式创建间谍对象:

chai.spy.object([ 'push', 'pop' ]);

有了茉莉花,你可以使用:

jasmine.createSpyObj('tape', ['play', 'pause', 'stop', 'rewind']);

什么是 Jest 等价物?

上下文:我目前正在将(打字稿)Jasmine 测试迁移到(打字稿)Jest。在这种情况下,迁移指南基本上是无用的:https://facebook.github.io/jest/docs/migration-guide.html 与任何相对较新的技术一样,在文档中找不到任何关于此的内容。

【问题讨论】:

    标签: jestjs


    【解决方案1】:

    我已经为 jest 编写了一个非常快速的 createSpyObj 函数,以支持旧项目。基本上是从 Jasmine 的实现中移植过来的。

    export const createSpyObj = (baseName, methodNames): { [key: string]: Mock<any> } => {
        let obj: any = {};
    
        for (let i = 0; i < methodNames.length; i++) {
            obj[methodNames[i]] = jest.fn();
        }
    
        return obj;
    };
    

    【讨论】:

    • ...Mock 在做什么?它只是像'import Mock = jest.Mock'这样的导入吗?
    • @acekizzy 我可以确认它是jest.Mock。它允许你模拟这样的方法:let obj = createSpyObj('', ['run']); obj.run.mockReturnValue(someValue);。请注意,在此实现中,baseName 不执行任何操作。如果能加上类型安全就更好了。
    【解决方案2】:
    const video = {
      play() {
        return true;
      },
    };
    
    module.exports = video;
    

    还有测试:

    const video = require('./video');
    
    test('plays video', () => {
      const spy = jest.spyOn(video, 'play');
      const isPlaying = video.play();
    
      expect(spy).toHaveBeenCalled();
      expect(isPlaying).toBe(true);
    
      spy.mockReset();
      spy.mockRestore();
    });
    

    在此处找到的文档:https://facebook.github.io/jest/docs/en/jest-object.html#jestspyonobject-methodname

    还有 jest.fn()

    const mockFn = jest.fn();
      mockFn();
      expect(mockFn).toHaveBeenCalled();
    
      // With a mock implementation:
      const returnsTrue = jest.fn(() => true);
      console.log(returnsTrue()); // true;
    

    https://facebook.github.io/jest/docs/en/jest-object.html#jestfnimplementation

    【讨论】:

      【解决方案3】:

      根据@Max Millington 的回答,我找到了jest.fn() 方法的解决方案:

      1. 创建模拟对象:

      const tape: any = {};

      1. 为模拟对象添加所需的方法

      tape['play'] = jest.fn();

      1. 您可以 spyOn 模拟方法,但首先将其分配给真实对象,例如我正在使用组件实例:

        // GIVEN
        comp.realTape = tape
        
        // WHEN
        spyOn( comp.realTape , 'play')
        comp.method()
        
        // THEN
        expect(comp.realTape.play).toHaveBeenCalledTimes(1)
        

      【讨论】:

        【解决方案4】:

        David 的回答帮助我走上了正轨。我在我的 Ionic3/Angular4 项目中对其进行了修改以使用 ionic-mocks (https://github.com/stonelasley/ionic-mocks)。

        在我的测试“助手”类中,我有这个:

        export function  createSpyObj (baseName: string, methodNames: string[]): { [key: string]: jasmine.Spy } {
          const obj: any = {}
          for (let i: number = 0; i < methodNames.length; i++) {
            obj[methodNames[i]] = jasmine.createSpy(baseName, () => {})
          }
          return obj
        }
        

        然后我可以在我的测试/规范文件中使用它。我将有问题的提供者注入为:

        { provide: AlertController, useFactory: () => AlertControllerMock.instance() },
        

        在 ionic-mocks 与 Jest 兼容之前,我必须复制我想要的模拟(使用 createSpyObj):

        class AlertMock {
          public static instance (): any {
            const instance: any = createSpyObj('Alert', ['present', 'dismiss'])
            instance.present.and.returnValue(Promise.resolve())
            instance.dismiss.and.returnValue(Promise.resolve())
        
            return instance
          }
        }
        
        class AlertControllerMock {
          public static instance (alertMock?: AlertMock): any {
        
            const instance: any = createSpyObj('AlertController', ['create'])
            instance.create.and.returnValue(alertMock || AlertMock.instance())
        
            return instance
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2020-11-22
          • 1970-01-01
          • 2022-08-07
          • 2021-06-20
          • 1970-01-01
          • 2023-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多