代码之家  ›  专栏  ›  技术社区  ›  helloitsjoe

反应测试库-避免getBy?

  •  0
  • helloitsjoe  · 技术社区  · 6 年前

    当使用React测试库测试组件时,我发现自己从 getBy* ,偶尔需要用 queryBy* (例如,如果我需要检查元素是否不存在)。我的测试结果是 getBy queryBy ,我最近一直在用 牢骚

    这让我想到。。。有什么理由使用 格特比

    像这样的断言会按预期失败,而无需抛出错误:

    expect(queryByText('Click me')).toBeInTheDocument();
    expect(queryByLabel('Name').value).toBe('George')
    

    牢骚

    编辑: 牢骚 只有 推荐用于断言某事是 在文档中:

    https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#using-query-variants-for-anything-except-checking-for-non-existence

    文章还建议使用 screen.queryBy screen.getBy 而不是从 render ,这简化了从一个函数到另一个函数的更改,因为您不再需要更新解构函数。

    0 回复  |  直到 5 年前
        1
  •  10
  •   TLadd    6 年前

    如前所述,getBy*和queryBy*之间的区别在于,如果找不到元素而queryBy*找不到元素,getBy*就会抛出一个错误。对我来说,如果我期望某个东西在那里,我总是使用getBy*并且只在我断言某个东西不在那里的场景中使用queryBy*。如果某个元素不在我期望的位置,我希望在测试中尽早了解它,无论在哪里进行getBy*调用。

    因此,我想说抛出错误的好处是,您总是确保您的测试失败将指向根问题(无法找到您期望存在的元素),而不是根问题的副作用(尝试在测试的稍后部分使用该元素)。

    示例测试:

        const { getByTestId, queryByTestId } = render(getComponent());
    
        const textInput = queryByTestId("textInput");
    
        fireEvent.change(textInput, { target: { value: "hello" } });
        fireEvent.change(textInput, { target: { value: "hi" } });
    

    Unable to fire a "change" event - please provide a DOM element.
    
          23 |     const textInput = queryByTestId("textInput") as any;
          24 |
        > 25 |     fireEvent.change(textInput, { target: { value: "hello" } });
             |               ^
          26 |     fireEvent.change(textInput, { target: { value: "hi" } });
          27 |
    

    所以它确实表明 textInput 找不到。如果我将其更改为getByTestId,则输出为

    Unable to find an element by: [data-testid="textInput"]
    
        <body>
          <div>
            <div>
              <button
                type="button"
              >
                Show the Text Input!
              </button>
            </div>
          </div>
        </body>
    
          21 |     const { getByTestId, queryByTestId, rerender } = render(getComponent());
          22 |
        > 23 |     const textInput = getByTestId("textInput") as any;
             |                       ^
          24 |
          25 |     fireEvent.change(textInput, { target: { value: "hello" } });
          26 |     fireEvent.change(textInput, { target: { value: "hi" } });
    

    在我看来,getBy*错误输出有两个优点:

    1. 它直接指向问题所在的那条线。在第一种情况下,不难发现查询“textInput”是问题所在。但这有点不直接。
    2. 当我使用getBy*时,它会自动打印DOM的外观。在确定为什么我要找的东西不存在时,这会很有帮助。一旦queryBy*测试失败,这可能是我将要采取的第一步,所以它自动出现是很好的。

    推荐文章