如何在 Kotlin 中使用单独的 profile/environment 数据源进行 Micronaut 测试?
How to use a separate profile/environment data source for Micronaut test in Kotlin?
我正在尝试为我用 Kotlin 编写的 Micronaut Web 应用程序使用两个数据源:一个带有 mysql 数据库,以及执行测试时要使用的内存 H2 数据库中的一个 .
我试过只使用 h2
数据库作为默认的生产数据源,所以关于它的配置字段应该是正确的。
通过执行 ./gradlew run
,应用程序 运行 与 mysql 数据源符合预期
- 我试过将数据源放在单独的配置文件中,
application.yml
和 application-test.yml
放在 src/main/resources/
目录中,并且只将 application-test.yml
放在 src/test/resources/
, 没有结果.
- 添加
@MicronautTest
注释声明 test
环境和 application = BookieSparaerverApplication
参数无效。
- 向
BookieServerApplication
添加 @TypeHint(Genre::class, Book::class, DefaultGenreRepository::class)
注释无效。
这些是src/main/resources/application.yml
配置文件的相关字段
datasources:
default:
url: 'jdbc:mysql://localhost:3306/bookie-server?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false'
dbCreate: create-update
driverClassName: com.mysql.cj.jdbc.Driver
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
username: root
password: root
jpa:
default:
entity-scan:
packages:
- 'com.transgressoft.bookieserver.domain'
properties:
hibernate:
hbm2ddl:
auto: update
show_sql: true
这是 src/test/resources/application-test.yml
文件:
datasources:
default:
url: ${JDBC_URL:`jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE`}
username: ${JDBC_USER:sa}
password: ${JDBC_PASSWORD:""}
driverClassName: ${JDBC_DRIVER:org.h2.Driver}
jpa:
default:
entity-scan:
packages:
- 'com.transgressoft.bookieserver.domain'
properties:
hibernate:
hbm2ddl:
auto: update
show_sql: true
当我执行测试时(代码中的 GenreControllerSpec
),看起来 EntityManager
bean 没有被创建,因此 DAO class 无法被实例化(在我的代码中是GenreRepository
class).
这是完整的日志消息:
Internal Server Error: Failed to inject value for parameter [entityManager] of class: com.transgressoft.bookieserver.domain.$DefaultGenreRepositoryDefinition$Intercepted
Message: No bean of type [javax.persistence.EntityManager] exists. Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
Path Taken: new $GenreControllerDefinition$Intercepted([GenreRepository genreRepository],BeanContext beanContext,Interceptor[] interceptors) --> new $DefaultGenreRepositoryDefinition$Intercepted([EntityManager entityManager],ConfigurationProperties applicationConfiguration,BeanContext beanContext,Interceptor[] interceptors)
io.micronaut.http.client.exceptions.HttpClientResponseException: Internal Server Error: Failed to inject value for parameter [entityManager] of class: com.transgressoft.bookieserver.domain.$DefaultGenreRepositoryDefinition$Intercepted
完整的项目代码可以在这里访问
https://github.com/octaviospain/bookie-server/tree/feature/jpa-and-hibernate 并重现上述日志只需执行 ./gradlew test
并打开报告,或者 运行 它激活日志。
编辑:我已经根据 Ivan Lopez 的建议更新了描述,但错误和预期结果保持不变。
我认为您误解了定义数据源的工作原理。
设置时:
datasources:
production:
...
test:
...
jpa:
production:
...
test:
...
您正在告诉 Micronaut:“我希望您创建 两个 数据源,一个名为 production
,另一个名为 test
同时 。这两个数据源都将对应用程序可用,您可以使用定义的名称(production
和 test
)和限定符注入它们。
您需要做的是在src/main/resources/application.yml
中只定义一个数据源。 Micronaut 使用 default
名称作为默认名称:
datasources:
default:
... // your production MySQL database
jpa:
default:
... // configuration for MySQL database
然后您可以覆盖 application.yml
中定义的任何内容,只需使用以下内容创建 src/test/resources/application-test.yml
:
datasources:
default:
... // your test H2 database
jpa:
default:
... // configuration for H2 database
希望它有意义。您可以在此处找到更多相关信息:https://docs.micronaut.io/latest/guide/index.html#config
您的示例应用程序使用 micronaut-hibernate-jpa
的 1.1.1,不支持
jpa:
default:
entity-scan:
packages:
- 'com.transgressoft.bookieserver.domain'
您必须使用 jpa.default.packages-to-scan
而不是 documentation 状态。
我正在尝试为我用 Kotlin 编写的 Micronaut Web 应用程序使用两个数据源:一个带有 mysql 数据库,以及执行测试时要使用的内存 H2 数据库中的一个 .
我试过只使用 h2
数据库作为默认的生产数据源,所以关于它的配置字段应该是正确的。
通过执行 ./gradlew run
- 我试过将数据源放在单独的配置文件中,
application.yml
和application-test.yml
放在src/main/resources/
目录中,并且只将application-test.yml
放在src/test/resources/
, 没有结果. - 添加
@MicronautTest
注释声明test
环境和application = BookieSparaerverApplication
参数无效。 - 向
BookieServerApplication
添加@TypeHint(Genre::class, Book::class, DefaultGenreRepository::class)
注释无效。
这些是src/main/resources/application.yml
配置文件的相关字段
datasources:
default:
url: 'jdbc:mysql://localhost:3306/bookie-server?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false'
dbCreate: create-update
driverClassName: com.mysql.cj.jdbc.Driver
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
username: root
password: root
jpa:
default:
entity-scan:
packages:
- 'com.transgressoft.bookieserver.domain'
properties:
hibernate:
hbm2ddl:
auto: update
show_sql: true
这是 src/test/resources/application-test.yml
文件:
datasources:
default:
url: ${JDBC_URL:`jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE`}
username: ${JDBC_USER:sa}
password: ${JDBC_PASSWORD:""}
driverClassName: ${JDBC_DRIVER:org.h2.Driver}
jpa:
default:
entity-scan:
packages:
- 'com.transgressoft.bookieserver.domain'
properties:
hibernate:
hbm2ddl:
auto: update
show_sql: true
当我执行测试时(代码中的 GenreControllerSpec
),看起来 EntityManager
bean 没有被创建,因此 DAO class 无法被实例化(在我的代码中是GenreRepository
class).
这是完整的日志消息:
Internal Server Error: Failed to inject value for parameter [entityManager] of class: com.transgressoft.bookieserver.domain.$DefaultGenreRepositoryDefinition$Intercepted
Message: No bean of type [javax.persistence.EntityManager] exists. Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
Path Taken: new $GenreControllerDefinition$Intercepted([GenreRepository genreRepository],BeanContext beanContext,Interceptor[] interceptors) --> new $DefaultGenreRepositoryDefinition$Intercepted([EntityManager entityManager],ConfigurationProperties applicationConfiguration,BeanContext beanContext,Interceptor[] interceptors)
io.micronaut.http.client.exceptions.HttpClientResponseException: Internal Server Error: Failed to inject value for parameter [entityManager] of class: com.transgressoft.bookieserver.domain.$DefaultGenreRepositoryDefinition$Intercepted
完整的项目代码可以在这里访问
https://github.com/octaviospain/bookie-server/tree/feature/jpa-and-hibernate 并重现上述日志只需执行 ./gradlew test
并打开报告,或者 运行 它激活日志。
编辑:我已经根据 Ivan Lopez 的建议更新了描述,但错误和预期结果保持不变。
我认为您误解了定义数据源的工作原理。 设置时:
datasources:
production:
...
test:
...
jpa:
production:
...
test:
...
您正在告诉 Micronaut:“我希望您创建 两个 数据源,一个名为 production
,另一个名为 test
同时 。这两个数据源都将对应用程序可用,您可以使用定义的名称(production
和 test
)和限定符注入它们。
您需要做的是在src/main/resources/application.yml
中只定义一个数据源。 Micronaut 使用 default
名称作为默认名称:
datasources:
default:
... // your production MySQL database
jpa:
default:
... // configuration for MySQL database
然后您可以覆盖 application.yml
中定义的任何内容,只需使用以下内容创建 src/test/resources/application-test.yml
:
datasources:
default:
... // your test H2 database
jpa:
default:
... // configuration for H2 database
希望它有意义。您可以在此处找到更多相关信息:https://docs.micronaut.io/latest/guide/index.html#config
您的示例应用程序使用 micronaut-hibernate-jpa
的 1.1.1,不支持
jpa:
default:
entity-scan:
packages:
- 'com.transgressoft.bookieserver.domain'
您必须使用 jpa.default.packages-to-scan
而不是 documentation 状态。