我想监视一个导出为命名导出的子函数,但是,我们似乎无法监视它。
我们假设我在(df
.groupby("id")
.agg(F.first(F.coalesce("code")),
F.first(F.coalesce("name")))
.collect())
中有两个名为[Row(id='a', code='code1', name='name2')]
和add
的函数,并将它们导出为名为exports:
multiply
测试文件使用operations.js
尝试监视const add = (a, b) => {
return a + b
}
const multiply = (a, b) => {
let result = 0
for (let i = 0; i < b; i++) {
result = add(a, result)
}
return result
}
export { add, multiply }
函数:
sinon-chai
结果是
add
但是,如果我像下面这样直接调用import chai, { expect } from 'chai'
import sinon from 'sinon'
import sinonChai from 'sinon-chai'
import * as operations from './operations'
chai.use(sinonChai)
describe('multiply', () => {
it('should call add correctly', () => {
sinon.spy(operations, 'add')
operations.multiply(10, 5)
expect(operations.add).to.have.been.callCount(5)
operations.add.restore()
})
})
,它会通过测试:
AssertionError: expected add to have been called exactly 5 times, but it was called 0 times
似乎sinon-spy为operations.add
创建了一个新引用,但describe('multiply', () => {
it('should call add correctly', () => {
sinon.spy(operations, 'add')
operations.add(0, 5)
operations.add(0, 5)
operations.add(0, 5)
operations.add(0, 5)
operations.add(0, 5)
expect(operations.add).to.have.been.callCount(5)
operations.add.restore()
})
})
函数仍然使用已绑定的旧引用。
如果将这些函数命名为exports,则监视此operations.add
函数的multiply
函数的正确方法是什么?
一般来说,如何监视被测试的父函数的子函数,它们都被命名为exports?
[UPDATE]
add
函数就是一个例子。我的主要观点是测试父函数是否调用子函数。但是,我不希望该测试依赖于子功能的实现。所以,我只是想窥探子函数是否被调用。您可以想象multiply
函数是multiply
函数,multiply
函数是registerMember
函数。 (这两个函数都命名为exports。)
答案 0 :(得分:-2)
对于我自己的问题,我有一个解决方法。
当前,multiply()
函数与add()
函数紧密耦合。这使得很难测试,特别是当导出的函数获得新的引用时。
因此,为了监视子函数调用,我们可以将子函数传递给父函数。是的,它是dependency injection
。
因此,在operations.js
中,我们会将addFn
注入multiply()
并按如下方式使用它:
const add = (a, b) => {
return a + b
}
const multiply = (a, b, addFn) => {
let result = 0
for (let i = 0; i < b; i++) {
result = addFn(a, result)
}
return result
}
export { add, multiply }
然后,在测试中,我们可以监视add()
这样的函数:
describe('multiply', () => {
it('should call add correctly', () => {
sinon.spy(operations, 'add')
operations.multiply(10, 5, operations.add)
expect(operations.add).to.have.been.callCount(5)
operations.add.restore()
})
})
现在,它的工作原理是测试是否正确调用子函数。
(注意:缺点是我们需要更改multiply()
功能)