首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Jest中扩展模拟构造函数的实例

如何在Jest中扩展模拟构造函数的实例
EN

Stack Overflow用户
提问于 2017-12-05 20:01:17
回答 2查看 3.6K关注 0票数 5

我想在取笑单元测试中增加(但不是完全替换)模拟构造函数的实例。

我想在实例中添加一些值,但是保留自动模拟的Jest的优点。

例如:

A.js

代码语言:javascript
复制
module.exports = class A {
  constructor(value) {
    this.value = value;
  }
  getValue() {
    return this.value;
  }
}

为了获得一些汽车模仿的威严:

代码语言:javascript
复制
jest.mock('./A');

使用自动锁,实例有一个模拟的.getValue()方法,但它们没有.value属性。

记录在案的模拟构造器的方法是:

代码语言:javascript
复制
// SomeClass.js
module.exports = class SomeClass {
  m(a, b) {}
}

// OtherModule.test.js
jest.mock('./SomeClass');  // this happens automatically with automocking
const SomeClass = require('./SomeClass')
const mMock = jest.fn()
SomeClass.mockImplementation(() => {
  return {
    m: mMock
  }
})

const some = new SomeClass()
some.m('a', 'b')
console.log('Calls to m: ', mMock.mock.calls)

A中使用这种方法

代码语言:javascript
复制
jest.mock('./A');

const A = require('./A');

A.mockImplementation((value) => {
  return { value };
});

it('does stuff', () => {
  const a = new A();
  console.log(a); // -> A { value: 'value; }
});

这样做的好处是,您可以对返回的值做任何您想做的事情,比如初始化.value

缺点是:

  • 您不会免费获得任何自动锁定,例如,我需要自己将.getValue()添加到实例中
  • 对于创建的每个实例,您需要有一个不同的jest.fn()模拟函数,例如,如果我创建两个A实例,每个实例都需要为.getValue()方法提供自己的jest.fn()模拟函数。
  • SomeClass.mock.instances不填充返回的值(GitHub票)

有一件事不起作用(我希望Jest能施点魔法):

代码语言:javascript
复制
A.mockImplementation((value) => {
  const rv = Object.create(A.prototype); // <- these are mocked methods
  rv.value = value;
  return rv;
});

不幸的是,所有实例都共享相同的方法(正如人们预期的那样,但值得一试)。

我的下一步是通过检查原型(我猜)来生成模拟,我自己,但我想看看是否有一个既定的方法。

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-24 06:23:00

事实证明,这是固定的(从jest 24.1.0开始),问题中的代码就像预期的一样工作。

回顾一下,给定的类A

A.js

代码语言:javascript
复制
module.exports = class A {
  constructor(value) {
    this.value = value;
  }
  setValue(value) {
    this.value = value;
  }
}

这个测试现在将通过:

A.test.js

代码语言:javascript
复制
jest.mock('./A');

const A = require('./A');

A.mockImplementation((value) => {
  const rv = Object.create(A.prototype); // <- these are mocked methods
  rv.value = value;
  return rv;
});

it('does stuff', () => {
  const a = new A('some-value');
  expect(A.mock.instances.length).toBe(1);
  expect(a instanceof A).toBe(true);
  expect(a).toEqual({ value: 'some-value' });
  a.setValue('another-value');
  expect(a.setValue.mock.calls.length).toBe(1);
  expect(a.setValue.mock.calls[0]).toEqual(['another-value']);
});
票数 2
EN

Stack Overflow用户

发布于 2019-02-13 18:16:44

以下几点对我有用:

代码语言:javascript
复制
A.mockImplementation(value => {
   const rv = {value: value};
   Object.setPrototypeOf(rv, A.prototype);
   return rv
})
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47661741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档