首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对模拟无状态状态的混淆使用sinon、enyzme和ES6导入来响应组件帮助函数

对模拟无状态状态的混淆使用sinon、enyzme和ES6导入来响应组件帮助函数
EN

Stack Overflow用户
提问于 2016-07-29 17:47:52
回答 2查看 904关注 0票数 1

目前,我正在尝试对React组件进行单元测试,并且在模拟函数(辅助函数)方面遇到了一些混乱。模块看起来如下所示

代码语言:javascript
复制
export const someHelper = () => {
  return ( <div></div> )
}

const MyComponent = () => {
  return (
    <span>
      {someHelper()}
    </span>
  )
}
export default MyComponent

然后这就是测试文件的样子。

代码语言:javascript
复制
import chai, { expect } from 'chai'
import chaiEnzyme from 'chai-enzyme'
import sinon from 'sinon'
import { shallow } from 'enzyme'
import React from 'react'

import MyComponent, { someHelper } from './MyComponent'

describe('MyComponent test', function (){
  it.only('should call someHelper once', function () {
    let spy = sinon.spy(someHelper)
    let myComponent = shallow(
      <MyComponent />
    )
    expect(spy.callCount).to.equal(1)
  })
})

但是,当callCount = 0时,此测试将失败。我认为这可能与someHelper函数的上下文有关,所以我做了以下修改

代码语言:javascript
复制
export const helpers = {
  someHelper () {
    ...
  }
}
const MyComponent = () => {
   ...
   {helpers.someHelper()}
   ...
}

_

代码语言:javascript
复制
import MyComponent, { helpers } ...

describe(...{
  it(...{
    let spy = sinon.spy(helpers.someHelper)
     ...
  })
})

但是,在callCount等于0的情况下,这个测试仍然失败。然后我做了这些改变

代码语言:javascript
复制
describe(...{
  it(...{
    let spy = sinon.spy(helpers, 'someHelper')
     ...
  })
})

然后测试就通过了。

为什么要将someHelper附加到helpers对象才能使测试正常工作?当spy(object, 'myfunc')显示一个spy(myFunc)选项时,为什么我必须使用最后一个spy(myFunc)方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-29 18:11:48

为什么要将someHelper附加到helpers对象才能使测试正常工作?

Sinon必须能够用一个间谍/存根包装版本替换对现有函数的引用,而且只有当该引用存储在一个对象中(本例中是helpers)时,它才能这样做。

它基本上是这样的:

代码语言:javascript
复制
let functionToSpyOn = helpers.someHelper;
let spy = sinon.spy(functionToSpyOn);
helpers.someHelper = spy;

这里的另一个复杂问题是,原始代码必须通过这个引用调用函数,所以这样的代码也不能工作:

代码语言:javascript
复制
const someHelper     = () => { ... }
export const helpers = { someHelper }
const MyComponent    = () => {
   ...
   {someHelper()}
   ...
}

原因是MyComponent没有使用存储在helpers中的引用,后者是被Sinon替换的引用。这就是组件需要使用helpers.someHelper()的原因。

为什么我要用最后一个spy(object, 'myfunc')方法.

这同样与用包装的函数替换函数有关。

...when sinon文档显示一个spy(myFunc)选项?

我发现这个成语通常用处有限。正如您可能认为的那样,它不会监视对myFunc的所有调用,除非这些调用是对spy()的结果的间谍对象进行的。

例如:

代码语言:javascript
复制
let callback = (err, result) => { ... }
...
let spy = sinon.spy(callback);
someFuncToTest(spy);
expect(spy.callCount).to.equal(1);

因此,不是直接传递回调函数,而是传递间谍。

票数 3
EN

Stack Overflow用户

发布于 2016-07-29 18:19:04

这个问题不是特定的反应或罪过,而是一般的JS。

如果这样的事情发生

代码语言:javascript
复制
var spiedMethod = (...args) => {
  console.log('spy!');
  return object.method(...args);
};

这将创建一个不替换原始object方法的新函数。如果调用object.method,则不会调用spiedMethod --原来的方法将被调用。要在object上替换它,应该修改对象:

代码语言:javascript
复制
object.method = spiedMethod;

这正是罪人间谍所做的。

代码语言:javascript
复制
let spy = sinon.spy(myFunc);

为提供的函数返回间谍sinon.spy(myFunc)。为了监视调用,应该调用spy而不是myFunc

除非像这样的事情被做了

代码语言:javascript
复制
helpers.someHelper = sinon.spy(helpers.someHelper);

Sinon不可能将spy函数与间谍方法相关联。这里是

代码语言:javascript
复制
sinon.spy(helpers, 'someHelper')

来拯救你。它本质上是做helpers.someHelper = spy的,但也在内部保存原始方法,所以当调用helpers.someHelper.restore()时,它可以执行helpers.someHelper = someHelperOriginal

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38664714

复制
相关文章

相似问题

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