Невозможно запустить тесты для базы данных h2 в памяти, скорее она работает на PostgreSQL - PullRequest
0 голосов
/ 23 сентября 2018

(у меня есть несколько связанных вопросов, поэтому я выделю их жирным шрифтом)

У меня есть приложение для воспроизведения .

  • play: 2.6.19
  • scala: 2.12.6
  • h2: 1.4.197
  • postgresql: 42.2.5
  • play-slick / play-slick-evolutions: 3.0.1
  • slick-pg: 0.16.3

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

Однако мой тест всегда выполняется на базе данных PostgreSQL, которую я настраиваю и использую.

# application.conf
slick.dbs.default.profile="slick.jdbc.PostgresProfile$"
slick.dbs.default.db.driver="org.postgresql.Driver"
slick.dbs.default.db.url="jdbc:postgresql://localhost:5432/postgres"

Вот мой тест test/dao/TodoDAOImplSpec.scala.

package dao

import play.api.inject.guice.GuiceApplicationBuilder
import play.api.test.{Injecting, PlaySpecification, WithApplication}

class TodoDAOImplSpec extends PlaySpecification {
  val conf = Map(
    "slick.dbs.test.profile" -> "slick.jdbc.H2Profile$",
    "slick.dbs.test.db.driver" -> "org.h2.Driver",
    "slick.dbs.test.db.url" -> "jdbc:h2:mem:test;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=FALSE"
  )
  val fakeApp = new GuiceApplicationBuilder().configure(conf).build()
  //val fakeApp = new GuiceApplicationBuilder().configure(inMemoryDatabase()).build()
  //val fakeApp = new GuiceApplicationBuilder().configure(inMemoryDatabase("test")).build()
  "TodoDAO" should {
    "returns current state in local pgsql table" in new WithApplication(fakeApp) with Injecting {
      val todoDao = inject[TodoDAOImpl]
      val result = await(todoDao.index())
      result.size should_== 0
    }
  }
}

Для fakeApp я пробую все три, но ни один из них не работает должным образом - мой тест все еще выполняется на моей локальной таблице PostgreSQL (в которой есть 3элементы), поэтому тест не пройден.

Что я пробовал / нашел:

Во-первых, inMemoryDatabase() просто возвращает Map("db.<name>.driver"->"org.h2.Driver", "db.<name>.url"->""jdbc:h2:mem:play-test-xxx"), что выглядит очень похоже на мое confкарта.Однако есть 2 основных различия:

  • inMemoryDatabase использует db.<name>.xxx, в то время как моя карта conf использует slick.dbs.<name>.db.xxx. Какой из них должен быть правильным?

Во-вторых, переименуйте conf ключи карты в "slick.dbs.default.profile", "slick.dbs.default.db.driver"and" slick.dbs.default.db.url "выдаст ошибку.

[error] p.a.d.e.DefaultEvolutionsApi - Unknown data type: "status_enum"; SQL statement:
ALTER TABLE todo ADD COLUMN status status_enum NOT NULL [50004-197] [ERROR:50004, SQLSTATE:HY004]

cannot create an instance for class dao.TodoDAOImplSpec

  caused by @79bg46315: Database 'default' is in an inconsistent state!

Вывод интересен - связан ли он с использованием мной типа PostgreSQL ENUM и slick-pg ?(См. slick-pg проблему с h2 ). Означает ли это, что это правильная конфигурация для запуска тестов h2 в памяти? Если это так, возникает вопрос Как подделать PostgreSQL ENUM в h2 .

В-третьих,Я следую этой теме , запускаю sbt '; set javaOptions += "-Dconfig.file=conf/application-test.conf"; test' с тестовым файлом конфигурации conf/application-test.conf:

include "application.conf"

slick.dbs.default.profile="slick.jdbc.H2Profile$"
slick.dbs.default.db.driver="org.h2.Driver"
slick.dbs.default.db.url="jdbc:h2:mem:test;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=FALSE"

Не удивительно, что я получаю ту же ошибку, что и 2-е испытание.

Мне кажется, что 2-е и 3-е испытания указывают на правильное направление (будет работать над этим). Но почему мы должны установить name на default? Любой другой лучший подход?

1 Ответ

0 голосов
/ 23 сентября 2018

В режиме воспроизведения база данных по умолчанию: по умолчанию .Однако вы можете изменить его на любое другое имя базы данных, но вам нужно также добавить имя базы данных.Например, я хочу иметь базу данных comment с таблицей user:

CREATE TABLE comment.User(
id                      int(250)         NOT NULL AUTO_INCREMENT,
username                varchar(255), 
comment                 varchar(255), 
PRIMARY KEY             (id)); 

Затем мне нужно иметь конфигурацию для подключения к ней (добавить ее в application.conffile):

db.comment.url="jdbc:mysql://localhost/comment"
db.comment.username=admin-username
db.comment.password="admin-password"

Вы можете иметь базу данных test для тестирования, как указано выше, и использовать ее в своем тесте.

Локальные тесты базы данных : Почему бы не иметь локальную базу данных, как у вас на производстве?Данные отсутствуют, и выполнение теста на локальном компьютере не затрагивает производственную базу данных;зачем вам дополнительная база данных?

Несоответствующее состояние : это когда MYSQL, который вы написали, изменяет состояние текущей базы данных в базе данных, которое может быть основано на создании новой таблицы или когда вы хотите удалитьit.

Также status_enum не распознается как команда MySQL, очевидно.Попробуйте команды, которые вы хотите использовать в консоли MySQL, если вы не уверены в этом.

...