测试一个动作创建者时,如何避免测试实现细节?

时间:2019-10-16 13:42:32

标签: redux react-testing-library

我是测试的新手,我正在为使用Redux的大型React应用编写测试,并且尝试遵循React Testing库的“避免测试实现细节”原则。

但是我不确定在正确地调用动作创建者时如何进行操作。我计划分别测试动作创建者,因此无需确保他们在这种情况下分派动作。

假设我要管理的项目列表。如果我以用户身份删除或创建一个,则希望列表中发生更改。我可以通过使组件断开连接并通过一个卑鄙的间谍作为动作创建者来轻松地测试动作创建者是否被调用,但这将测试实现细节(在我的情况下还有其他缺点)。如果要以模拟用户期望的行为的方式进行测试,则动作创建者需要将其动作实际分派给reducer并更改商店。这就需要一个单独的测试API,该API本身就有问题。重构动作创建者以检查它们是否被测试调用以跳过常规API调用不是一个好选择。

进行此操作的最佳方法是什么?我怀疑我对此考虑得有些过多,并且有一个简单的解决方案,但到目前为止我一直找不到或提出任何建议。

1 个答案:

答案 0 :(得分:0)

这就是我要做的。首先,我将按照this example进行测试。我将渲染显示列表并连接到商店的组件。

在这一点上,我将使用fireEvent模拟与您的应用进行交互的用户。例如,您可以模拟单击删除项目的按钮。模拟点击后,将分派该操作,将更新商店并重新渲染该应用程序。然后,我将检查列表是否正确更新。

/*
In this test I'm assuming the output of List is something like this:
<ol>
  <li>Foo <button>Delete Foo</button></li>
  <li>Bar <button>Delete Bar</button></li>
  <li>Baz <button>Delete Baz</button></li>
</ol>
*/
test('It's possible to remove elements from the list', () => {
  const { getByText, queryByText } = renderWithRedux(<List />)
  expect(getByText('Foo')).toBeInTheDocument()
  fireEvent.click(getByText('Delete Foo'))
  expect(queryByText('Foo')).not.toBeInTheDocument()
})