Rspec: Hồi mảng.should == other_array 'nhưng không quan tâm đến đơn hàng


235

Tôi thường muốn so sánh các mảng và đảm bảo rằng chúng chứa các phần tử giống nhau, theo bất kỳ thứ tự nào. Có cách nào ngắn gọn để làm điều này trong RSpec không?

Đây là những phương pháp không được chấp nhận:

#to_set

Ví dụ:

expect(array.to_set).to eq another_array.to_set

hoặc là

array.to_set.should == another_array.to_set

Điều này không thành công khi các mảng chứa các mục trùng lặp.

#sort

Ví dụ:

expect(array.sort).to eq another_array.sort

hoặc là

array.sort.should == another_array.sort

Điều này không thành công khi các phần tử mảng không thực hiện #<=>


7
Không phải thông minh, nhưng so sánh to_setsizethực sự không làm những gì bạn muốn. Ví dụ [a, b, b] sẽ khớp với [a, a, b]. Chúc mừng!
Jo Liss

3
Đối với những người vấp ngã ở đây tự hỏi ngược lại: trật tự nên giống nhau . Sử dụng các eqkhớp, ví dụ:expect([1, 2]).to_not eq([2, 1])
Dennis

Câu trả lời:


263

Thử array.should =~ another_array

Tài liệu tốt nhất về điều này tôi có thể tìm thấy là chính mã, ở đây .


Điều này không có thứ tự trong tài khoản, vì vậy đây không phải là một câu trả lời chấp nhận được, phải không? Trích dẫn từ các tài liệu : Passes if actual contains all of the expected regardless of order..
Joshua Muheim

16
Tiêu đề của bài đăng này: "Rspec: Mảng mảng.should == other_array Kẻ nhưng không quan tâm đến đơn hàng"
x1a4

3
Điều này hiện được ghi nhận chính thức dưới các trình so khớp toán tử
Kelvin

7
Nếu bạn đang sử dụng cú pháp "mong đợi" mới được tìm thấy trong rspec 3.0, hãy xem câu trả lời từ @JoshKovach.
clozach

46
Cú pháp Rspec 3.0 được expect([1, 2, 3]).to match_array([2, 1, 3])xem: stackoverflow.com/a/19436763/33226
Gavin Miller

238

Kể từ RSpec 2.11, bạn cũng có thể sử dụng match_array.

array.should match_array(another_array)

Mà có thể dễ đọc hơn trong một số trường hợp.

[1, 2, 3].should =~ [2, 3, 1]
# vs
[1, 2, 3].should match_array([2, 3, 1])

8
yup, chỉ cần nâng cấp lên đường ray 4 và = ~ ngừng hoạt động khi match_array hoạt động tốt, cảm ơn!
opsb

2
Tôi không biết nếu điều đó dễ đọc hơn. Bây giờ nó đọc giống như nó phải là một kết hợp chính xác, nhưng nó không phải là. Squiggle trước đó đủ mơ hồ không có nghĩa gì cho một mảng, vì vậy tôi không có định kiến. Có lẽ đó chỉ là tôi.
Trejkaz

1
Đối với "chính xác", bạn luôn luôn có eq(), vì vậy tôi đoán match_array()là đủ mơ hồ đối với tôi.
awendt

Điều này không làm việc cho tôi trên danh sách theo thứ tự. Nó nghĩ rằng các danh sách, có cùng các mục theo một thứ tự khác nhau, là như nhau. :-(
djangofan

FWIW match_arraylà bí danh cho contain_exactly( tài liệu )
Ruy Diaz


13

Sử dụng match_array, lấy một mảng khác làm đối số hoặc contain_exactlylấy mỗi phần tử làm đối số riêng biệt và đôi khi hữu ích cho khả năng đọc. ( tài liệu )

Ví dụ:

expect([1, 2, 3]).to match_array [3, 2, 1]

hoặc là

expect([1, 2, 3]).to contain_exactly 3, 2, 1

3

Đối với RSpec 3 sử dụng contain_exactly :

Xem https://relishapp.com/rspec/rspec-recectations/v/3-2/docs/built-in-matchers/contain-exactly-matcher để biết chi tiết, nhưng đây là trích xuất:

Bộ so khớp chứa_exactly cung cấp một cách để kiểm tra các mảng với nhau theo cách bỏ qua sự khác biệt trong thứ tự giữa mảng thực tế và mảng dự kiến. Ví dụ:

    expect([1, 2, 3]).to    contain_exactly(2, 3, 1) # pass
    expect([:a, :c, :b]).to contain_exactly(:a, :c ) # fail

Như những người khác đã chỉ ra, nếu bạn muốn khẳng định điều ngược lại, rằng các mảng phải phù hợp với cả nội dung và thứ tự, sau đó sử dụng eq, tức là:

    expect([1, 2, 3]).to    eq([1, 2, 3]) # pass
    expect([1, 2, 3]).to    eq([2, 3, 1]) # fail

1

không được ghi chép lại rất tốt nhưng tôi đã thêm các liên kết

Tài liệu Rspec3

expect(actual).to eq(expected)


Tài liệu Rspec2

expect([1, 2, 3]).to match_array([2, 3, 1])


11
Cả hai đều mong đợi (thực tế) .to eq (dự kiến) và mong đợi (thực tế) .to match_array (dự kiến) hoạt động trong rspec3, nhưng chúng đang làm những việc khác nhau. #match_array bỏ qua việc đặt hàng, trong khi #eq thì không.
gucki

1
Điều này không trả lời câu hỏi, vì OP đặc biệt yêu cầu bỏ qua đơn đặt hàng.
NobodysNightmare

Đúng! Điều này làm việc cho tôi. Một so sánh thất bại nếu thứ tự của các yếu tố không giống nhau. Cảm ơn bạn! Tôi tham khảo .to eqphương pháp, không phải match_array.
djangofan
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.