Подтвердить что ты не робот

Режим H2 postgresql, похоже, не работает для меня

Привет, мое приложение обращается к базе данных Postgres, и у меня есть много предопределенных запросов (Rank, Parition, сложное соединение и т.д.). Я запускаю Postgres. Теперь я хочу перейти на модульное тестирование этих запросов с небольшими тестовыми данными. Итак, я начал с H2/Junit. Я узнал, что большинство запросов Postgres, таких как Rank, Partition, Complex case при обновлении и т.д. Поэтому я подумал о том, чтобы использовать режим совместимости H2 PosgreSQL, думая, что все запросы postgres будут работать на H2, пожалуйста, исправьте меня, если я ошибаюсь.

Я последовал за документом H2, говорящим, что для использования режима PostgreSQL используйте URL-адрес базы данных jdbc: h2: ~/test; MODE = PostgreSQL или оператор SQL SET MODE PostgreSQL.

Я включил режим, используя SET MODE PostgreSQL, и я попытался запустить один из запросов, который включает rank(), и работает в postgres, но он не работает H2. Это дает мне следующее исключение.

Function "RANK' not found; in SQL statement

Пожалуйста, объясните, что я новичок в H2 и тестировании базы данных. Заранее спасибо. Я использую драйвер H2 jdbc для запуска запросов postgres, думая, что режим совместимости H2 Posgress позволит мне запускать запросы postgres.

4b9b3361

Ответ 1

Итак, я подумал о том, чтобы использовать режим совместимости H2 PosgreSQL, думая, что все запросы postgres будут работать на H2, пожалуйста, исправьте меня, если я ошибаюсь

Я боюсь, что это не так.

H2 пытается эмулировать синтаксис PostgreSQL и поддерживает несколько функций и расширений. Он никогда не будет полностью соответствовать поведению PostgreSQL и не поддерживает все функции.

Доступны только следующие параметры:

  • Использовать PostgreSQL при тестировании; или
  • Прекратить использование функций, не поддерживаемых H2

Я предлагаю использовать Pg для тестирования. Относительно просто написать тестовый жгут, который initdb экземпляра postgres и запускает его для тестирования, а затем срывает его после.

Обновление на основе комментариев:

Нет жесткой линии между тестами "unit" и "integration". В этом случае H2 также является внешним компонентом. Тесты пуристского модуля имели бы фиктивный ответчик на запросы как часть тестового жгута. Тестирование против H2 является таким же "интеграционным" испытанием, как тестирование против PostgreSQL. Тот факт, что он in-process и in-memory является удобством, но не функционально значимым.

Если вы хотите unit test, вы должны написать другую цель базы данных для своего приложения, чтобы идти рядом с вашими позициями "PostgreSQL", "SybaseIQ" и т.д. Назовите это, скажем, "MockDatabase". Это должно просто вернуть ожидаемые результаты из запросов. Он действительно не запускает запросы, он существует только для проверки поведения остальной части кода.

Лично я считаю, что гигантская трата времени, но то, что сделает пурист, проверяющий блок, чтобы избежать введения внешних зависимостей в тестовую жгуту.

Если вы настаиваете на том, чтобы тестировать единицы измерения (в отличие от интеграции) для ваших компонентов БД, но не можете/не будем писать макетный интерфейс, вы должны найти способ использовать существующий. H2 был бы разумным кандидатом для этого, но вам нужно будет написать новый бэкэнд с новым набором запросов, которые работают для H2, вы не можете просто повторно использовать свой сервер PostgreSQL. Как мы уже установили, H2 не поддерживает все функции, которые вам нужно использовать с PostgreSQL, поэтому вам придется искать разные способы сделать то же самое с H2. Одним из вариантов было бы создание простой базы данных H2 с "ожидаемыми" результатами и простыми запросами, которые возвращают эти результаты, полностью игнорируя реальную схему приложения. Единственный реальный недостаток здесь в том, что это может быть серьезной болью для поддержания... но это модульное тестирование.

Лично я просто тестирую PostgreSQL. Если я не тестирую отдельные классы или модули, которые автономны, как узко сопряженные четко определенные единицы, мне все равно, кто-то называет это "единицей" или "интеграцией". Я буду unit test, скажем, классы проверки данных. Для кода интерфейса базы данных пуристское тестирование модулей имеет мало смысла, и я просто сделаю тесты интеграции.

В то время как наличие встроенной базы данных в базе данных для этого удобно, это не требуется. Вы можете написать тестовую проводку, чтобы установочный код initdb нового PostgreSQL и запускает его; то код разрыва убивает постмастера и удаляет datadir. Я больше об этом писал в этом ответе.

См. также:

Что касается:

Если все запросы с ожидаемыми концевыми наборами данных отлично работают в Postgress, я могу предположить, что он будет работать отлично во всех остальных dbs

Если я понимаю, что вы говорите правильно, то да, этот случай - если остальная часть вашего кода работает с набором данных из PostgreSQL, он должен, как правило, работать с набором данных, содержащим одни и те же данные из другой базы данных. До тех пор, пока он использует простые типы данных, а не функции, специфичные для базы данных, конечно.