Làm cách nào để bạn kiểm tra sự không tồn tại của một phần tử bằng thư viện jest và react-testing-library?


96

Tôi có một thư viện thành phần mà tôi đang viết các bài kiểm tra đơn vị để sử dụng Jest và thư viện thử nghiệm phản ứng. Dựa trên một số đạo cụ hoặc sự kiện nhất định, tôi muốn xác minh rằng một số yếu tố nhất định không được hiển thị.

getByText,, getByTestIdv.v. ném và lỗi react-testing-librarynếu phần tử không được tìm thấy khiến quá trình kiểm tra không thành công trước khi expecthàm kích hoạt.

Làm thế nào để bạn kiểm tra một cái gì đó không tồn tại trong jest bằng cách sử dụng thư viện phản ứng thử nghiệm?

Câu trả lời:


202

Từ Tài liệu thư viện thử nghiệm DOM - Giao diện và Biến mất

Phần tử xác nhận không có mặt

Các getByphương thức tiêu chuẩn gây ra lỗi khi chúng không thể tìm thấy một phần tử, vì vậy nếu bạn muốn xác nhận rằng một phần tử không có trong DOM, bạn có thể sử dụng queryBycác API để thay thế:

const submitButton = screen.queryByText('submit')
expect(submitButton).toBeNull() // it doesn't exist

Các queryAllphiên bản API trả về một mảng các nút phù hợp. Độ dài của mảng có thể hữu ích cho các xác nhận sau khi các phần tử được thêm vào hoặc xóa khỏi DOM.

const submitButtons = screen.queryAllByText('submit')
expect(submitButtons).toHaveLength(2) // expect 2 elements

not.toBeInTheDocument

Các jest-domthư viện tiện ích cung cấp cho các .toBeInTheDocument()khớp, có thể được sử dụng để khẳng định rằng một yếu tố là trong cơ thể của tài liệu, hay không. Điều này có thể có ý nghĩa hơn là xác nhận một kết quả truy vấn null.

import '@testing-library/jest-dom/extend-expect'
// use `queryBy` to avoid throwing an error with `getBy`
const submitButton = screen.queryByText('submit')
expect(submitButton).not.toBeInTheDocument()

4
Kentcdodds xấu của tôi, cảm ơn bạn. Tôi đã sử dụng getByTestIdvà gặp lỗi tương tự. Và, tôi không kiểm tra Câu hỏi thường gặp, xin lỗi. Thư viện tuyệt vời! Bạn có thể sửa đổi câu trả lời của mình để bao gồm `.toBeNull ();
SomethingOn vào

3
Tôi tin rằng liên kết ở trên là để trỏ đến các tài liệu của thư viện thử nghiệm phản ứng
pbre

2
Trang web tài liệu mới đã được xuất bản cách đây vài ngày. Tôi nên sử dụng một liên kết lâu dài hơn. Cảm ơn vì bản cập nhật @pbre!
kentcdodds


6
queryByTextđối với những người muốn tương đương với getByTextđiều đó là không an toàn
S ..

22

Sử dụng queryBy/ queryAllBy.

Như bạn nói, getBy*getAllBy*ném một lỗi nếu không tìm thấy gì.

Tuy nhiên, các phương thức tương đương queryBy*queryAllBy*thay vào đó trả về nullhoặc []:

queryBy

queryBy*các truy vấn trả về nút phù hợp đầu tiên cho một truy vấn và trả về nullnếu không có phần tử nào khớp. Điều này hữu ích để xác nhận một phần tử không có mặt. Điều này sẽ ném ra nếu tìm thấy nhiều hơn một kết quả phù hợp (sử dụng queryAllBy thay thế).

Các queryAllBy* truy vấn queryAllBy trả về một mảng gồm tất cả các nút phù hợp cho một truy vấn và trả về một mảng trống ( []) nếu không có phần tử nào khớp.

https://testing-library.com/docs/dom-testing-library/api-queries#queryby

Vì vậy, đối với hai cụ thể mà bạn đã đề cập, thay vào đó bạn sẽ sử dụng queryByTextqueryByTestId, nhưng chúng hoạt động cho tất cả các truy vấn, không chỉ hai truy vấn đó.


2
Đây là cách tốt hơn câu trả lời được chấp nhận. API này có mới hơn không?
RubbelDieKatz

1
Cảm ơn những lời tốt đẹp! Về cơ bản, đây có cùng chức năng với câu trả lời được chấp nhận , vì vậy tôi không nghĩ đó là một API mới hơn (nhưng tôi có thể nhầm). Sự khác biệt thực sự duy nhất giữa câu trả lời này và câu trả lời được chấp nhận là câu trả lời được chấp nhận nói rằng chỉ có phương thức thực hiện điều này ( queryByTestId) trong khi thực tế có hai bộ phương thức tổng thể, trong đó queryByTestIdlà một ví dụ cụ thể.
Sam

Cảm ơn, tôi thích điều này hơn thiết lập id thử nghiệm
Hylle

13

Bạn phải sử dụng queryByTestId thay vì getByTestId.

Đây là một ví dụ mã mà tôi muốn kiểm tra xem thành phần có id "car" không tồn tại hay không.

 describe('And there is no car', () => {
  it('Should not display car mark', () => {
    const props = {
      ...defaultProps,
      base: null,
    }
    const { queryByTestId } = render(
      <IntlProvider locale="fr" messages={fr}>
        <CarContainer{...props} />
      </IntlProvider>,
    );
    expect(queryByTestId(/car/)).toBeNull();
  });
});

4

getBy * đưa ra lỗi khi không tìm thấy phần tử, vì vậy bạn có thể kiểm tra điều đó

expect(() => getByText('your text')).toThrow('Unable to find an element');

0

Bạn có thể sử dụng thư viện react-native-testing-"getAllByType" và sau đó kiểm tra xem thành phần có rỗng hay không. Có lợi thế là không phải đặt TestID, cũng nên hoạt động với các thành phần của bên thứ ba

 it('should contain Customer component', () => {
    const component = render(<Details/>);
    const customerComponent = component.getAllByType(Customer);
    expect(customerComponent).not.toBeNull();
  });

Loại vi phạm này vi phạm tiền đề là không có chi tiết triển khai (chẳng hạn như tên thành phần) trong thử nghiệm.
RubbelDieKatz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.