测试是否已在rootReducer中导入所有Reducer

时间:2016-09-22 15:02:11

标签: javascript reactjs redux react-redux

我有一个rootReducer导入所有单独的reducer,如下所示:

ITestContext

由于这个reducer导入所有东西很重要,我认为测试import { combineReducers } from 'redux'; import departments from './departments'; import indicators from './indicators'; import versions from './versions'; import projects from './projects'; // combine all reducers to a single reducer, state will be linked to a reducer via the key used here const rootReducer = combineReducers({ versions, departments, indicators, projects, }); export default rootReducer; 中所有已定义的缩减器是否都是导入是有意义的。我能想到的唯一方法是使用./src/reducers来检查fs(没有./src/reducersindex)中的文件数量,然后检查rootReducer包含许多减速器。

看起来像一个丑陋的测试,也有点脆弱。但是,当您忘记包含减速器时,通过失败的测试通知仍然是非常好的。测试是否已导入所有减速器的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

我听说你来自哪里,但我不认为你想在测试中处理这个问题。随着应用程序的增长,您可能需要更深层次的reducer树。例如。您的projects减速器可能由多个减速器组成,您必须管理哪些减速器需要从哪里导入。文件系统测试将变得越来越脆弱。通常,导入和文件结构是项目的实现细节,您希望测试项目的行为。

但是想要立即反馈未能连接减速器是完全有道理的。我尝试在构建级别处理它。假设您正在使用Webpack,请查看this plugin是否可以解决您的问题。它检测未使用的出口。将其添加到您的插件

new UnusedFilesWebpackPlugin({ pattern: 'src/reducers/**' })

当你的文件没有被导入时,你的版本会警告你。由于它适用于模块,因此您不必担心目录结构(除了确保模式匹配您要检查的所有文件)。

答案 1 :(得分:0)

您建议可能工作的方法,但我同意这样的事情会很脆弱,甚至可能无法测试您所关注的行为。

退后一步,查看您发布的代码的行为。如果你要把它抽象成英文,它可能看起来像这样:

  1. 导入名为combineReducers
  2. 的函数
  3. 导入我想要包含的每个缩减器
  4. 调用combineReducers,并传递包含我想要包含的每个reducer的对象
  5. 导出调用combineReducers
  6. 的结果

    您似乎只关注#3,这取决于#1和#2是否正确。如果你想测试用你期望的参数调用combineReducers,为什么不存根这个函数并断言那个行为呢?

    您可以将SinonJS用于stub combineReducers,并且在require()根减速器之后,您可以断言combineReducers被调用一次,并且它被调用包含您期望的键和值的Object。以下是我可以做的事情(使用mocha测试框架,chai进行断言):

    import * as Redux from 'redux';
    import sinon from 'sinon';
    import chai, {expect} from 'chai';
    import sinonChai from 'sinon-chai';
    
    import departments from './departments';
    import indicators from './indicators';
    import versions from './versions';
    import projects from './projects';
    
    chai.use(sinonChai);
    
    describe('Root Reducer', () => {
        before(() => {
            sinon.stub(Redux, 'combineReducers');
            require('./path/to/your/root/reducer');
        });
    
        after(() => {
            Redux.combineReducers.restore();
        });
    
        it('should use all of the created reducers', () => {
            const expectedReducers = {
                versions,
                departments,
                indicators,
                projects
            };
    
            expect(Redux.combineReducers).to.have.callCount(1);
            expect(Redux.combineReducers).to.be.calledWith(expectedReducers);
        });
    });
    

    这种方法优于你建议的方法是它不依赖文件夹中存在的任意数量的文件,并且负责保持测试中预期值的变量就是这样如果要添加新的reducer或删除旧的reducer,则需要进行修改。