Unit testing 测试Redux:减速器的测试是否应该使用动作?

Unit testing 测试Redux:减速器的测试是否应该使用动作?,unit-testing,redux,Unit Testing,Redux,我目前正在学习Redux。 到目前为止,当我发现如何管理状态应用程序时,我不想关注与框架的任何集成(如React)。我只是想很好地理解Redux背后的想法和概念 我参加了丹·阿布拉莫夫在星期四上的课程 我喜欢他通过测试他的应用程序解释的方式,所以我开始以同样的方式使用Redux 我用Redux构建了一个应用程序。当然,它有多个减速器和动作。 我不会在这里分享任何代码,因为它没有特别的兴趣 更重要的是如何处理测试和重复使用 我不知道用减缩器的相应操作测试减缩器是否有意义,或者我是否应该在测试中模拟

我目前正在学习Redux。 到目前为止,当我发现如何管理状态应用程序时,我不想关注与框架的任何集成(如React)。我只是想很好地理解Redux背后的想法和概念

我参加了丹·阿布拉莫夫在星期四上的课程

我喜欢他通过测试他的应用程序解释的方式,所以我开始以同样的方式使用Redux

我用Redux构建了一个应用程序。当然,它有多个减速器和动作。 我不会在这里分享任何代码,因为它没有特别的兴趣

更重要的是如何处理测试和重复使用

我不知道用减缩器的相应操作测试减缩器是否有意义,或者我是否应该在测试中模拟这些操作。

我开始模拟操作,因为一开始,我认为分离测试是一个好主意,并且简化程序和操作之间没有依赖关系。(这是我在大多数教程中看到的。但在教程中,他们通常构建小型应用程序)

现在,我发现有时候我会得到一个与相应操作不同的模拟,即使我的测试很好,当我使用dispatch(myAction())时,它可能会在一个真正的应用程序中中断,因为它与execpected不同

我应该在减速器测试中使用我的操作吗?

非常感谢你对此的解释

编辑:一些代码有更好的解释

减速器 减速器试验 所以在这里,而不是

{
    type: CREATE_PROJECT,
    payload: {
        id: idNewProject,
        name: 'New project !'
    }
}

我是否应该调用我的操作
createProject('newproject!')

感谢您的澄清。原来我在评论中误解了你。这里有一个更有帮助的解释

在测试减速机时,不应使用实际操作,例如
createProject('newproject!')

减缩器是简单的状态机,接收输入并返回输出。您的测试应该检查它们是否确实做到了这一点,其中:
input=previous state>output=next state
。是的,它仍然算作单元测试(我不明白为什么它不会)


我发现这个

简短的回答是“是”,否则您将如何确保减速器按预期运行?通常:“减速器应在将动作应用到前一状态后返回新状态”;在@Ursus中,我添加了更多的代码,让您更好地理解我的意思(只是为了确定)。所以你可以在我的减速器测试中使用动作?那么它真的是“单元测试”吗?好的,那么我们如何确保我们的操作与模拟匹配呢?我们不能?我们只需要严格?因为我理解这一点的好处,但我也“担心”我的行为可能与我的模拟不同,并且当我使用我的行为时,我的还原程序可能无法按预期工作。是的,我认为我们可以通过严格和确保每个测试检查一件事情的组合来实现这一点。所以我的建议是:遵循“做一件事,把它做好”的原则,你应该会没事的。但不要感到被语言或规则所束缚;它们不应该妨碍你的热情。最终,只需为您的需求找到一个良好的平衡:)
it('CREATE_PROJECT if no project should only have the new project', done => {
    let idNewProject = uuid.v4()

    expect(
        projects(undefined, {
            type: CREATE_PROJECT,
            payload: {
                id: idNewProject,
                name: 'New project !'
            }
        })
    )
    .toEqual([{
        id: idNewProject,
        name: 'New project !',
        people: [],
        money: '€',
        operations: [],
        archived: false,
        closed: false
    }])

    done()
})
{
    type: CREATE_PROJECT,
    payload: {
        id: idNewProject,
        name: 'New project !'
    }
}