response['products'][0]['ids'][0]['product_id']
является String
: "123"
.
String#include?
вернет сюда true
для следующих входных данных: ""
, "1"
, "2"
, "3"
, "12"
, "23"
и "123"
- но это явно не то, что вы пытаетесь проверить!
Вы хотели проверить, что этот product_id
в этом списке; не то чтобы оно включало список.
Это немного необычный тест для запуска, поскольку ваши ожидания несколько размыты.
Если это приложение rails
(т.е. вы используете ActiveSupport
), тогда вы можете использовать Object#in?
, чтобы написать тест следующим образом:
expect(response['products'][0]['ids'][0]['product_id'])
.to be_in(product_1.id, product_2.id, product_3.id)
Или, если мы просто используем ванильный рубин, тогда, возможно, используем rspec
s satisfy
matcher :
expect(response['products'][0]['ids'][0]['product_id'])
.to satisfy { |product_id| [product_1.id, product_2.id, product_3.id].include?(product_id) }
Вы также можете испытать искушение просто изменить порядок аргументов - что технически работает, но немного сбивает с толку, так как в коде создается впечатление, что вы запускаете утверждения на неправильном объекте:
expect([product_1.id, product_2.id, product_3.id])
.to include(response['products'][0]['ids'][0]['product_id'])
Но вернемся к тому, что это "необычное испытание".
Предположительно, вы написали это так, потому что вы не уверены, в каком порядке будут перечислены id
с, т.е. какой продукт на самом деле будет response['products'][0]
.
Тест будет еще лучше, если вы либо:
- Сделал заказ известным (но я не могу посоветовать, как, не видя больше деталей), так что вам не нужен нечеткий сопоставитель, или
- Только 1
product
, возвращенный ответом в этом тесте, или
- Измените тест на чтение всех трех
product_id
с из ответа, а затем используйте сопоставитель match_array
.