Jest.js 笑话创建间谍对象

atmip9wb  于 2023-02-27  发布在  Jest
关注(0)|答案(5)|浏览(217)

使用Chai,可以创建间谍对象,如下所示:

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

茉莉花,你可以用途:

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

开玩笑的等价物是什么?
上下文:我目前正在将一个(typescript)Jasmine测试迁移到(typescript)Jest,迁移指南在这种情况下基本上是无用的:https://facebook.github.io/jest/docs/migration-guide.html与任何相对较新的技术一样,在文档中很难找到有关这方面的内容。

ccgok5k5

ccgok5k51#

我为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;
};
mcdcgff0

mcdcgff02#

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

zz2j4svz

zz2j4svz3#

根据@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)
z9ju0rcb

z9ju0rcb4#

感谢@大卫的回答!
即使在今天,要找到一个内置的解决方案也不容易。我修改了你的例子,因为你的例子中没有使用basename。当在测试中使用这个对象时,我总是不得不把它转换成未知的[Type],这是我不想做的。

export const createSpyObj = <T>(methodNames): { [key: string]:jest.Mock<any> } & { spyObj: T } => {

  const obj: { [key: string]: jest.Mock<any> } & { spyObj: T } = { 
spyObj: null } as any;

  for (let i = 0; i < methodNames.length; i++) {
     obj[methodNames[i]] = jest.fn();
  }

  obj.spyObj= obj as T;
  return obj;
};

有了这段代码,我可以在我测试的服务的构造函数中传递spyObj。

const injectedService = createSpyObj<InjectedService>(['something']);

injectedService.something.mockReturnValue(true);

const serviceToBeTested = new ServiceToBeTested(injectedService.spyObj);
expect(injectedService.something).toBeCalled();

一个警告是intellisense不再适用于methodName。

jckbn6z7

jckbn6z75#

David的回答帮助我走上了正确的轨道,我修改了它,以便在我的Ionic 3/Angular 4项目中使用ionic-mock(https://github.com/stonelasley/ionic-mocks)。
在我的测试“helper”类中,我有这样的代码:

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兼容之前,我必须复制我想要的mocks(它使用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
  }
}

相关问题