Тестирование массива Ruby Airbone не работает должным образом

У меня есть json ниже

{
    "menu": {
        "sections": [
            {
                "type": 4,
                "frames": [
                    {
                        "itens": []
                    }
                ],
                "order": 0
            },
            {
                "type": 4,
                "frames": [
                    {
                        "itens": [
                            {
                                "id": "1719016",
                                "type": 0,
                                "free": false
                            }
                        ]
                    }
                ],
                "order": 1
            }
        ]
    }
}

и тест ниже, который может проверить, есть ли у всех элементов json в массиве itens свойство ID:

expect_json_keys('menu.sections.0.frames.*.itens.*', :id)

Проблема в том, что этот тест работает нормально. Но должен потерпеть неудачу.

Мой тест терпит неудачу только тогда, когда я меняю свои ожидания на это:

expect_json_keys('menu.sections.0.frames.*.itens.0', :id)

Почему этот тест проходит успешно, а не проваливается при использовании itens.*

🤔 А знаете ли вы, что...
Ruby был создан в Японии Юкихиро Мацумото и впервые выпущен в 1995 году.


59
2

Ответы:

Решено

Я воспроизвел вашу проблему и попытался немного отладить.

Я впервые вижу эту беспроводную жемчужину (поэтому отнеситесь к следующему с долей скептицизма), но думаю, что проблема скрывается в самой воздушной реализации, вот, если быть точнее: https://github.com/brooklynDev/airborne/blob/master/lib/airborne/path_matcher.rb#L82

Эта строка предназначена для запуска блока ожидания (Вот этот в данном конкретном случае) для каждого элемента, соответствующего сегменту с подстановочными знаками, но для пустого массива она просто ничего не делает. Нет ожиданий - нет неудач.

Так что дело не в коде ваших тестов, а в самом драгоценном камне. В качестве обходного пути вы можете попробовать что-то. как следующее:

expect_json_types('menu.sections.0.frames.*.itens', :array_of_objects) # <= add this
expect_json_keys('menu.sections.0.frames.*.itens.*', :id)

например проверка типа значения перед проверкой самого значения - в этом случае происходит сбой с Expected array_of_objects got Array instead


Большое спасибо @konstantin-strukov. Это решение отлично работает для этого тестового примера.

Но в некоторых тестовых случаях мне все равно приходится писать дополнительный код.

Ожидание, которое вы написали, не соответствует этому json http://www.mocky.io/v2/5c827f26310000e8421d1e83. Хорошо, у меня есть тестовый пример, где он действительно должен провалиться. Я буду использовать ваше решение во многих случаях использования. Еще раз спасибо.

Но у меня есть несколько тестовых случаев, которые не должны давать сбоев, если у меня есть хотя бы одно заполненное свойство itens (http://www.mocky.io/v2/5c827f26310000e8421d1e83). expect_json_keys('menu.sections.0.frames.*.itens.?', :id) должно быть достаточно, но это не так, потому что он работает с использованием itens.* или itens.?. Я пытался подогнать ваше решение под эти тестовые примеры, но оно не сработало, как ожидалось.