简体   繁体   English

用笑话和酶进行稳健的测试

[英]Robust testing with jest and enzyme

I'm currently trying to improve the tests within a react project in which I am utilising Material UI.我目前正在尝试改进我使用 Material UI 的 React 项目中的测试。 I am utilising jest and enzyme to perform the tests.我正在利用笑话和酶来进行测试。

So far I've been using the .find to find the components, to perform actions on.到目前为止,我一直在使用.find来查找组件,以对其执行操作。 Recently I've stumbled upon an annoyance/issue that I have been unable to find the answer for.最近我偶然发现了一个我一直无法找到答案的烦恼/问题。 To pick a certain scenario I've chosen the one here below:为了选择某个场景,我在下面选择了一个:

I have a form in which a user inputs我有一个用户输入的表单

  • first name
  • last name
  • email电子邮件
  • phone number电话号码
  • and so forth...等等……

I am creating a wrapper for this form and the most reasonable approach for finding the fields to .simulate('change') have been to take the wrapper and doing the following:我正在为此表单创建一个包装器,查找.simulate('change')字段的最合理方法是采用包装器并执行以下操作:

// Arrange
const formWrapper = formWrapper(); // <--- A mount function to create the above described form
const firstNameField = formWrapper.find('input').at(1); // <--- This is currently my issue
const lastNameField = formWrapper.find('input').at(2); // <--- This is currently my issue
// ... and so forth

// Act
firstName.simulate('change', { target: { name: 'firstName', value: 'Bobby' },});
lastName.simulate('change', { target: { name: 'lastName', value: 'Brown' },});
// ... more simulations ofc

// Assert
// ... and some expects.

My annoyance is the way that I'm "fetching" my inputs.我的烦恼是我“获取”我的输入的方式。 The only reason I know that the firstName field is .at(1) is because I've looked into the HTML.我知道 firstName 字段是.at(1)的唯一原因是因为我查看了 HTML。 It is not a very robust method.这不是一个非常健壮的方法。 If I need to update that form, then the entire test will break, and I will have to figure out which fields are which once again.如果我需要更新那个表单,那么整个测试就会中断,我将不得不再次弄清楚哪些字段是哪些。

A small note is that I am using the Material UI Text Fields as my base component, but I have styled them after my requirements.一个小说明是,我使用Material UI 文本字段作为我的基本组件,但我已经根据我的要求对它们进行了样式设置。 I've tried passing in some custom prop to my components (eg test="firstNameField" ), but that is not a pretty solution as Material UI passes that along to all the child components.我尝试将一些自定义道具传递给我的组件(例如test="firstNameField" ),但这不是一个很好的解决方案,因为 Material UI 将其传递给所有子组件。 If I do this I could of course always just find .at(1) if I make the custom prop unique to each field.如果我这样做,我当然总是可以找到.at(1)如果我使自定义道具对每个字段都是唯一的。 However I don't think this is the way to do it either.但是,我认为这也不是这样做的方法。 There should be some other way that I am not aware of yet.应该还有其他一些我还不知道的方式。

So my question is:所以我的问题是:

Does someone know a more robust way to do this?有人知道更强大的方法来做到这一点吗?

EDIT:编辑:

After reading comments and suggestions, I've found that I might have been too specific in my question.阅读评论和建议后,我发现我的问题可能过于具体。 Of course the example (with inputs above), is one of the problems that I face, but this is also the case with other components.当然,这个例子(上面有输入)是我面临的问题之一,但其他组件也是如此。

Let's say that I on my above described form element, have two identical components (typography fields - more specifically paragraph tags), that both consist of the same base component, how would I go about differentiating these two?假设我在上面描述的表单元素上有两个相同的组件(排版字段 - 更具体地说是段落标签),它们都包含相同的基本组件,我将如何区分这两个组件? Would I be forced to give them unique IDs or is there some other way?我会被迫给他们唯一的 ID 还是有其他方法? And even if I did give them unique IDs, those would be passed down to all the children that the Material UI components have.即使我确实给了它们唯一的 ID,这些 ID 也会传递给 Material UI 组件拥有的所有子级。

You can use react-testing-library which gives you queries to select based on how user would interect with your app, in your case your form.您可以使用react-testing-library ,它为您提供查询以根据用户与您的应用程序的交互方式进行选择,在您的情况下是您的表单。

for example if you want to get your name input and you have correct htmlFor for your label you can use例如,如果您想输入姓名并且您的标签具有正确的 htmlFor,则可以使用

const nameField = getByLabelText('name');

Okay.好的。

So after some much research and documentation read-through I found that you can simply chain your .find() 's, and if you think that is not enough you can also use the .findWhere() if that more suits your flavor.因此,经过大量研究和通读文档后,我发现您可以简单地链接您的.find() ,如果您认为这还不够,您还可以使用.findWhere()如果这更适合您的口味。

So in the end what I ended up doing was to fetch the "field" which had the property name: 'firstName and which was an input field.所以最后我最终做的是获取具有属性name: 'firstName的“字段” name: 'firstName ,这是一个input字段。

The following code snippets illustrate:以下代码片段说明了:

const firstNameField = formWrapper.find({name: 'firstName'}).find('input');
const lastNameField = formWrapper.find({name: 'lastName'}).find('input');
const firstNameField = formWrapper.findWhere(n => n.name === 'firstName' && n.type === 'input');
const lastNameField = formWrapper.findWhere(n => n.name === 'lastName' && n.type === 'input');

This method removes the excessive amount of nodes from Material UI (all the children that has passed props from their parents).此方法从 Material UI 中删除过多的节点(所有从父级传递 props 的子级)。

I also found documentation pointing towards using the modified "enzyme" package that Material UI has built in, but so far that didn't change anything, regarding my issues, and the regular enzyme package works just fine.我还发现文档指向使用 Material UI 内置的修改后的“酶”包,但到目前为止,关于我的问题,没有任何改变,并且常规酶包工作得很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM