Javascript 依赖于其他吸气剂的单元测试Vuex吸气剂

Javascript 依赖于其他吸气剂的单元测试Vuex吸气剂,javascript,unit-testing,vue.js,vuex,jestjs,Javascript,Unit Testing,Vue.js,Vuex,Jestjs,我已经设法测试了与其他代码隔离的Vuex getter。当一个getter依赖于其他getter时,我现在面临一些问题,请参见以下示例: getters.js getters.spec.js 当被测试的getter依赖于其他具有参数的getter时,这意味着我在mock上引用了原始的getter.getFoo,这打破了mock的概念,因为测试开始相互关联。当getter增长,并且依赖关系图有几个级别时,它会使测试变得复杂 也许这就是方法,只是想检查一下我没有遗漏任何东西…我同意你的观点,在你的模

我已经设法测试了与其他代码隔离的Vuex getter。当一个getter依赖于其他getter时,我现在面临一些问题,请参见以下示例:

getters.js

getters.spec.js

当被测试的getter依赖于其他具有参数的getter时,这意味着我在mock上引用了原始的
getter.getFoo
,这打破了mock的概念,因为测试开始相互关联。当getter增长,并且依赖关系图有几个级别时,它会使测试变得复杂


也许这就是方法,只是想检查一下我没有遗漏任何东西…

我同意你的观点,在你的模拟中引用实际的合作者违背了模拟的目的。因此,我会直接返回您希望您的合作者返回的任何内容

在您的示例中,不要这样做:

// mock getters
const _getters = {
  getFoo: getters.getFoo(state)
}
const state = {
  name: 'stackoverflow'
}

describe('getFancyNames', () => {
  const getFoo = jest.fn()
  getFoo.mockReturnValueOnce('foo: stackoverflow')
  getFoo.mockReturnValueOnce('bar: stackoverflow')

  it('returns a collection of fancy names', () => {
    expect(getters.getFancyNames(state, { getFoo })).toEqual([
      'foo: stackoverflow',
      'bar: stackoverflow'
    ])
  })
})
您只需输入任何
getters即可。getFoo(state)
将返回:

const _getters = {
    getFoo: 'foobar' 
}
如果有一个getter接受一个附加参数,则只需返回一个返回常量的函数:

const _getters = {
    getFoo: x => 'foobar',
}

因为我使用的是Jest,所以Jest mock函数中有一个选项,让我们在调用时指定返回值:

mockReturnValue一次
mockReturnValue

更多信息可在此处找到:

使用与问题中相同的代码,可以这样解决:

// mock getters
const _getters = {
  getFoo: getters.getFoo(state)
}
const state = {
  name: 'stackoverflow'
}

describe('getFancyNames', () => {
  const getFoo = jest.fn()
  getFoo.mockReturnValueOnce('foo: stackoverflow')
  getFoo.mockReturnValueOnce('bar: stackoverflow')

  it('returns a collection of fancy names', () => {
    expect(getters.getFancyNames(state, { getFoo })).toEqual([
      'foo: stackoverflow',
      'bar: stackoverflow'
    ])
  })
})

我发现的一种更干净的方法是创建自己的模拟getters对象。只有当
getter
像问题一样使用未更改的
状态时,这才有效

const state={
名称:“stackoverflow”
}
描述('getFancyNames',()=>{
常数mocketters={
…getters,//可以跳过此操作
getFoo:getters.getFoo(state),//我们只覆盖需要的内容
};
它('返回一组奇特的名称',()=>{
expect(getters.getFancyNames(state,mockedGetters)).toEqual([
‘foo:stackoverflow’,
'bar:stackoverflow'
])
})
})
额外的 如果确实需要调用其他getter函数,只需将模拟getter对象传递到另一个模拟getter对象中。听起来比实际情况更糟

getters.py

export const getters={
getBar(state)={//新的超硬部件!
返回state.bar,
},
getFoo(state,getter)=>前缀{
返回`${prefix}:${state.name}和一些${getter.getBar}`;
},
getFancyNames(状态,getter){
返回[
getters.getFoo('foo'),
getters.getFoo('bar'))
]
}
}
const\u mockedGetters={
…getters,//可以跳过此操作
getFoo:getters.getFoo(state),//我们只覆盖需要的内容
};
常数mocketters={
.._mockedGetters,//使用模拟对象!
getBar:getters.getBar(state,\u mockedGetters),//我们只覆盖需要的内容
};
//根据需要继续往下走!

问题在于,您的测试将实际运行原始的getter,然后测试将无法通过,因为您的模拟包含生成与getter输出不同的输出的getter。我不确定是否遵循。您的测试运行以模拟的getter作为参数的getter。实际上,我正在我的一个项目中使用这种方法。你能给我举个例子,说明那会如何打破你的考试吗?哦,对不起,我想我现在看到了。您的
getFancyNames
方法使用不同的参数调用同一个getter两次。我的例子是,在这两种情况下,您都可以返回
foobar
。谢谢您的时间。你是对的,它是有效的,我想在大多数情况下,返回相同的值将是解决方案,甚至是最好的解决方案,因为你想隔离你的getters测试。我已经发布了一个答案,因为我找到了一种方法来实现这一点,使用
jest
,以防您感到好奇;)