如何用 Jest 模拟/替换对象的 getter 函数?

Posted

技术标签:

【中文标题】如何用 Jest 模拟/替换对象的 getter 函数?【英文标题】:How to mock/replace getter function of object with Jest? 【发布时间】:2017-09-27 14:10:28 【问题描述】:

在Sinon我可以做到以下几点:

var myObj = 
    prop: 'foo'
;

sinon.stub(myObj, 'prop').get(function getterFn() 
    return 'bar';
);

myObj.prop; // 'bar'

但是我怎样才能对 Jest 做同样的事情呢? 我不能只用jest.fn() 之类的东西覆盖函数,因为它不会替换getter

"无法设置get的值"

【问题讨论】:

【参考方案1】:

对于其他偶然发现此答案的人,Jest 22.1.0 引入了spy on getter and setter methods 的功能。

编辑:就像在下面的scieslak's answer 中一样,因为您可以监视 getter 和 setter 方法,您可以对它们使用 Jest 模拟,就像使用任何其他函数一样:

class MyClass 
  get something() 
    return 'foo'
  


jest.spyOn(MyClass, 'something', 'get').mockReturnValue('bar')
const something = new MyClass().something

expect(something).toEqual('bar')

【讨论】:

@taystack 能够监视 getter/setter 是能够像普通函数一样模拟它们的必要步骤。我更新了我的答案以更明确地说明这一点,并在示例代码中添加了一个模拟。 something property does not existjest@24.9.0["module:metro-react-native-babel-preset",而 it works fine with scieslak solution 将间谍完全设置在 awesomeness 实例上。在rspec 中,我将使用一个名为any_instance 的方法,并且我将模拟/存根any_instance 该类。 jest official spyOn documentation 和您的示例之间的语法存在明显差异。在那个例子中,玩笑监视了一个对象文字 const video = get play() return true; ,; @fabrizo jest.spyOn(MyClass, 'something', 'get').mockReturnValue('bar') 应该是 jest.spyOn(MyClass.prototype, 'something', 'get')。 mockReturnValue('bar')【参考方案2】:

你可以使用Object.defineProperty

Object.defineProperty(myObj, 'prop', 
  get: jest.fn(() => 'bar'),
  set: jest.fn()
);

【讨论】:

非常感谢,这行得通。有时我注意到我不需要更多关于某些库/框架的知识,而是 javascript 的基本工作原理。我可以问一个后续问题:如果我希望我的模拟只替换原始函数一次但下一次调用应该由原始函数再次处理,我将如何模拟这个函数? 这行得通,但是当我尝试在我的 beforeEach() 调用中执行此操作时,它会因Cannot redefine property 而失败。这是为什么呢? @clu 将configurable: true 添加到您的defineProperty 函数中。这应该可以解决问题 请注意 - 与模拟相比 - 它不会在每个测试用例结束时“取消模拟”你的 getter,所以 - 如果其他测试依赖于 getter 的原始返回值 - 你可以运行一个测试和整个套件得到不同的结果。 向下滚动到弗兰尼的答案。它是最近的。【参考方案3】:

天哪,我来过这里很多次了。最终找出正确的解决方案。 如果您只关心间谍活动。去找@Franey 的答案。但是,如果您确实需要为 getter 存根值,那么您可以这样做

class Awesomeness 
  get isAwesome() 
    return true
  


describe('Awesomeness', () => 
  it('is not always awesome', () => 
    const awesomeness = new Awesomeness
    jest.spyOn(awesomeness, 'isAwesome', 'get').mockReturnValue(false)

    expect(awesomeness.isAwesome).toEqual(false)
  )
)

【讨论】:

我收到一个错误,指出该属性不存在。它看起来也像其他答案在类上调用 spyOn 而你在实例上调用它。 我在调用实例时看到了同样的情况——“属性不存在”。

以上是关于如何用 Jest 模拟/替换对象的 getter 函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何用 jest 解开单个实例方法

在R Shiny中,如何用observe替换observeEvent?

如何用笑话模拟 S3?

如何用玩笑模拟组件中使用的“嵌套”角度服务

如何用模拟和预定义的答案替换异步调用?

如何用 jest 测试 redux saga?