ReactJS:如何在 Jest 中通过动作触发减速器
Posted
技术标签:
【中文标题】ReactJS:如何在 Jest 中通过动作触发减速器【英文标题】:ReactJS: how to trigger reducer with action in Jest 【发布时间】:2017-09-26 01:36:22 【问题描述】:我正在进行减速器测试。但是带有action函数的reducer返回状态异常。
reducer.react-test.js
import reducer from '../../test_module/reducer';
describe('Test Reducer', () =>
const initStatus = id: -1, list: [] ;
it('1. has default state', () =>
expect(reducer(initStatus, type: 'unexpected' )).toEqual(
...initStatus
);
);
it('2. has added once', () =>
expect(reducer(initStatus, type: "ADD" )).toEqual(
...initStatus,
id: 0,
list: [0],
);
);
it('3. has added twice', () =>
const afterAddOnce = reducer(initStatus, type: "ADD" );
expect(reducer(afterAddOnce, type: "ADD" )).toEqual(
...initStatus,
id: 1,
list: [0,1],
);
);
)
reducer.js
export default function reducer(state=
id: -1, list: [],
, action)
switch(action.type)
case "ADD":
state.id = state.id + 1;
state.list.push(state.id);
return
...state,
;
return state;
文件夹结构
.
├── __test__
│ └── test_module
│ └── reducer.react-test.js
└── test_module
└── reducer.js
我的第一个和第二个测试用例按预期工作。
但是,当我尝试触发动作两次时,我存储了第一个动作的返回状态。但是返回状态是意外的,它执行了两次ADD
动作。 (我预计只有一次)
因此我在运行 jest
时得到了这个结果:
FAIL __test__/test_module/reducer.react-test.js
● Test Reducer › has added twice
expect(received).toEqual(expected)
Expected value to equal:
"id": 1, "list": [0, 1]
Received:
"id": 2, "list": [0, 1, 2]
Difference:
- Expected
+ Received
Object
- "id": 1,
+ "id": 2,
"list": Array [
0,
1,
+ 2,
],
我一定误解了用action触发reducer函数的用法。我希望能找到一些正确的方法来触发减速器并获得预期的结果。
【问题讨论】:
【参考方案1】:罪魁祸首可以在你的减速器中找到,特别是这些行:
state.id = state.id + 1;
state.list.push(state.id);
这里的 reducer 既改变了状态,又返回了一个新的状态。改变状态是不好的做法,并且会导致奇怪的效果(就像你正在经历的那样)
所以 '2.已添加一次' 测试会将 id 增加到 0。这将在下一次测试期间保留在内存中,其中 initialStatus 的 id 将为 0,而不是 -1。在我们的 reducer 中,state 指向 initialStatus。所以调用state.id = status.id + 1;
会增加initialStatus 的id 字段,列表也是如此。这就是为什么 ADD 操作似乎被调用了 3 次的原因。
远离减速器中的突变可以帮助解决这个问题。
case "ADD":
const newId = state.id + 1;
return
id: newId,
list: state.list.concat([newId])
;
记住,永远不要在 reducer 中改变状态,总是返回新的状态! (http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments)
【讨论】:
以上是关于ReactJS:如何在 Jest 中通过动作触发减速器的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Reactjs 中通过 websocket 使用 MQTT?