【问题标题】:How can I test a store singleton?如何测试商店单身人士?
【发布时间】:2017-05-24 19:37:55
【问题描述】:

我已经在使用 redux-mock-store 实现单元测试。

我想在使用商店单例的 react-native 应用程序上执行集成测试套件。然而,即使console.logs 达到了 store 上的 reducer 功能(并且似乎工作正常)状态并没有改变。

// __tests__/things.js
jest.mock('../app/store')
import 'react-native'

import * as selectors from '../app/selectors'
import * as sagas from '../app/sagas'
import { store } from '../app/store'

describe('Things', () => {
  it('should toggle', async () => {
    const previousCounter = selectors.count()
    await sagas.increment()
    expect(store.getState().count).toEqual(previousCounter)
  })
})

同时模拟商店实现:

// __mocks__
import { createStore } from 'redux'
import rootReducer from '../reducers'
export const store = createStore(rootReducer, {})

编辑:样本化简器

// app/reducers.js 
function rootReducer (state = { count: 0 }, action = {}) {
    const count = state.count + 1
    return { ...state, count }
}

一切都很好,但状态没有改变。如果我通过订阅商店来实现观察者,我会看到正在调度的动作系列。

【问题讨论】:

  • 你也应该展示你的减速器。
  • 完成,我添加了一个示例。然而,正如我所说,在真正的代码库中,reducers 正在按预期工作。这是因为他们正在将更改保存到“其他”商店而不是模拟的单例。
  • 看起来你的模拟商店没有连接到 sagas。所以调用sagas.increment 不会对商店产生任何影响。
  • 它执行@just-boris,它启动动作并且reducer正在适当地读取状态。我的 sagas 没有直接联系,因为他们也将商店用作单身人士。这是一个自定义实现。

标签: javascript reactjs react-native redux jestjs


【解决方案1】:

我会回答我的问题,作为其他人解决这个问题的一种手段。

与许多其他教程和指南一样,不鼓励使用存储单例。我理解的是隔离依赖项和组件的问题。但是,如果您仍然决定使用它来获得舒适感(就像我们一样),您将需要在其他部门需要时模拟该组件,因为它们不会被递归地模拟。

因此,除了具有与此类似的文件夹结构的表单...

.
├── app
|    ├── __mocks__
|    |    |
|    |    └── store.js
|    └── store.js

对于同时需要 './store.js' 的那些部门,您需要导出模拟版本。

// app/store.js

// Choose mock dependency over current store for tests
if (process.env.NODE_ENV === 'test') {
  jest.mock('./store')
}

这样,无论何时在测试期间需要store.js,它都会递归地选择模拟版本而不是真实版本。

可能存储单例需要更多的宣传才能被选为主流的 redux 实践。不应被视为反模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 2020-06-18
    相关资源
    最近更新 更多