基本的reducer可能会改变app状态

时间:2017-09-23 06:30:09

标签: ecmascript-6 redux immutability reducers

我正在使用Redux扩展运算符来希望将状态保存为不可变对象。

但是,我正在努力使最简单的单元测试失败。

我认为错误可能与不可变因素有关,但是我没有正确使用扩展运算符吗?

这是我的单元测试:



describe('app logic', () => {
  it('initialises app', () => {
    const newState = reducer(INITIAL_STATE, {type: "NEXT"})
    const expectState = {
      start: true,
      render_component: null,
      requests: {},
      results: {},
    }
    console.log('newState', newState)
    console.log('expected state', expectState)
    expect(newState).to.equal(expectState)
  })
})




这是我的减速机



export const INITIAL_STATE = {
  start: false,
  render_component: null,
  requests: {},
  results: {}
}

export const next = (state) => {
  if (state === INITIAL_STATE) {
    return {
      ...state,
      start: true,
    }
  }
  return state
}

export function reducer(state = INITIAL_STATE, action) {
  switch (action.type) {
    case 'NEXT':
      return next(state)
    default:
      return state
  }
}




我打印两个对象,它们看起来一样。 我收到错误:

1)app逻辑初始化app:

  AssertionError: expected { Object (start, render_component, ...) } to equal { Object (start, render_component, ...) }

1 个答案:

答案 0 :(得分:1)

不确定您正在使用哪个测试库,但通常使用类似.equal的名称来测试严格相等(===),这意味着(至少在对象的情况下)被比较的两件事实际上必须引用完全相同的对象。所以,例如,

const original = { a: 1 }; // creates a new object, assign it
const testMe = { a: 1 }; // creates another new object, assign it
console.log( original === testMe )   // false

计算结果为false,因为虽然对象具有相同的内容,但它们不会引用完全相同的对象。它们是独立的,独立创建的,恰好具有相同内容的对象。将其与

进行比较
const original = {a: 1}; // create a new object
const testMe = original;  // create another reference to the same object
console.log( original === testMe );  // true

所以当你回来时

return {
  ...state,
  start: true,
}

您正在创建并返回一个新对象,因此它自然可以引用您创建并分配给变量名expectedState的同一对象。

如果您感兴趣的不是严格的相等,而只是两个对象中的内容相同,则存在除.equal之外的其他方法,通常用deep命名(因为他们深入到对象/数组/无论如何检查值是否相同)。

Chai.js在其文档中包含expect(x).to.equal(y)expect(x).to.deep.equal(y)的示例:http://chaijs.com/api/bdd/#method_equal

您的测试库可能具有非常相似(如果不相同)的语法。