目前,我正在尝试对React组件进行单元测试,并且在模拟函数(辅助函数)方面遇到了一些混乱。模块看起来如下所示
export const someHelper = () => {
return ( <div></div> )
}
const MyComponent = () => {
return (
<span>
{someHelper()}
</span>
)
}
export default MyComponent然后这就是测试文件的样子。
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函数的上下文有关,所以我做了以下修改
export const helpers = {
someHelper () {
...
}
}
const MyComponent = () => {
...
{helpers.someHelper()}
...
}_
import MyComponent, { helpers } ...
describe(...{
it(...{
let spy = sinon.spy(helpers.someHelper)
...
})
})但是,在callCount等于0的情况下,这个测试仍然失败。然后我做了这些改变
describe(...{
it(...{
let spy = sinon.spy(helpers, 'someHelper')
...
})
})然后测试就通过了。
为什么要将someHelper附加到helpers对象才能使测试正常工作?当spy(object, 'myfunc')显示一个spy(myFunc)选项时,为什么我必须使用最后一个spy(myFunc)方法?
发布于 2016-07-29 18:11:48
为什么要将
someHelper附加到helpers对象才能使测试正常工作?
Sinon必须能够用一个间谍/存根包装版本替换对现有函数的引用,而且只有当该引用存储在一个对象中(本例中是helpers)时,它才能这样做。
它基本上是这样的:
let functionToSpyOn = helpers.someHelper;
let spy = sinon.spy(functionToSpyOn);
helpers.someHelper = spy;这里的另一个复杂问题是,原始代码必须通过这个引用调用函数,所以这样的代码也不能工作:
const someHelper = () => { ... }
export const helpers = { someHelper }
const MyComponent = () => {
...
{someHelper()}
...
}原因是MyComponent没有使用存储在helpers中的引用,后者是被Sinon替换的引用。这就是组件需要使用helpers.someHelper()的原因。
为什么我要用最后一个
spy(object, 'myfunc')方法.
这同样与用包装的函数替换函数有关。
...when sinon文档显示一个
spy(myFunc)选项?
我发现这个成语通常用处有限。正如您可能认为的那样,它不会监视对myFunc的所有调用,除非这些调用是对spy()的结果的间谍对象进行的。
例如:
let callback = (err, result) => { ... }
...
let spy = sinon.spy(callback);
someFuncToTest(spy);
expect(spy.callCount).to.equal(1);因此,不是直接传递回调函数,而是传递间谍。
发布于 2016-07-29 18:19:04
这个问题不是特定的反应或罪过,而是一般的JS。
如果这样的事情发生
var spiedMethod = (...args) => {
console.log('spy!');
return object.method(...args);
};这将创建一个不替换原始object方法的新函数。如果调用object.method,则不会调用spiedMethod --原来的方法将被调用。要在object上替换它,应该修改对象:
object.method = spiedMethod;这正是罪人间谍所做的。
let spy = sinon.spy(myFunc);为提供的函数返回间谍sinon.spy(myFunc)。为了监视调用,应该调用spy而不是myFunc。
除非像这样的事情被做了
helpers.someHelper = sinon.spy(helpers.someHelper);Sinon不可能将spy函数与间谍方法相关联。这里是
sinon.spy(helpers, 'someHelper')来拯救你。它本质上是做helpers.someHelper = spy的,但也在内部保存原始方法,所以当调用helpers.someHelper.restore()时,它可以执行helpers.someHelper = someHelperOriginal。
https://stackoverflow.com/questions/38664714
复制相似问题