用于集成测试的 Dropwizard-Hibernate 事务处理
Dropwizard-Hibernate Transaction handling for Integration Tests
我的 dropwizard 应用程序有一个集成测试,我在其中使用休眠 h2 数据库来存储数据。对于测试的第二部分,我使用 jersey-testframework 来处理资源和休息调用。
为了使这两个部分协同工作,我必须为每个案例创建一个 TestRule。
休眠:
@ClassRule
public static final SessionFactoryRule sessionFactoryRule = new SessionFactoryRule(User.class, HibernateUtil.getHibernateClasses());
public static final ProgramDAO programDao = new ProgramDAO(sessionFactoryRule.getSessionFactory());
球衣:
@ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addProvider(new AuthDynamicFeature(
new OAuthCredentialAuthFilter.Builder<User>()
.setAuthenticator(new OAuthAuthenticator(userManagement))
.setAuthorizer(new OAuthAuthorizer())
.setPrefix(TOKEN_TYPE)
.buildAuthFilter()))
.addProvider(new AuthValueFactoryProvider.Binder<>(User.class))
.addProvider(RolesAllowedDynamicFeature.class)
.addResource(new AdResource(urlMapperMock, programDao))
.build();
h2 hibernate db 配置
Configuration configuration = new Configuration()
.setInterceptor(new SoftDeleteInterceptor())
.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect")
.setProperty("hibernate.connection.driver_class", "org.h2.Driver")
.setProperty("hibernate.connection.url", "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")
.setProperty("hibernate.hbm2ddl.auto", "create")
.setProperty("hibernate.default_batch_fetch_size", "200")
.setProperty("hibernate.show_sql", "false")
.setProperty("hibernate.current_session_context_class", "thread");
现在,当我在资源上调用 请求 时...
@Test
public void resourceCheck() {
javax.ws.rs.core.Response response = resources.getJerseyTest().target(Ad.TABLE_NAME).request().header(HEADER_KEY_AUTHORIZATION, HEADER_VALUE_VALID_BEARER_TOKEN).get();
assertThat(response.getStatus()).isEqualTo(200);
}
...抛出如下错误
ERROR [2016-01-26 11:23:21,594] org.glassfish.grizzly.servlet.ServletHandler: service exception:
! org.hibernate.HibernateException: getNamedQuery is not valid without active transaction
! at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
! at com.sun.proxy.$Proxy74.getNamedQuery(Unknown Source) ~[na:na]
! at io.dropwizard.hibernate.AbstractDAO.namedQuery(AbstractDAO.java:57) ~[dropwizard-hibernate-0.9.1.jar:0.9.1]
! at com.ad4mat.api.db.core.AdDAO.findAllByUser(AdDAO.java:36) ~[classes/:na]
! at com.ad4mat.api.resource.AdResource.getAll(AdResource.java:79) ~[classes/:na]
显然没有针对测试用例的事务处理,但应该有一个。
我的普通 dropwizard 应用程序运行良好。通过使用 @UnitOfWork
.
标记资源来处理事务
当我在 dao 中添加一个手动事务时...
public List<Ad> findAllByUser(User user) {
currentSession().beginTransaction();
Query query = namedQuery("ad.findAllByUser")
.setParameter(User.FOREIGN_COLUMN_ID, user.getId());
return query.list();
集成测试有效,但我的应用程序会抛出嵌套事务异常。
所以我的问题是:
如何使@UnitOfWork 注释可用于集成测试过程。显然缺少事务处理实现。我必须 jersey.register()
Dropwizard-Hibernate 的某个组件吗?
从 dropwizard 版本 0.9.2 开始,可以在 Jersey 上下文之外使用 @UnitOfWork 注释。
也许您正在寻找 dropwizard 更新;那么您应该能够在任何上下文中执行数据库操作(最重要的是 junit/testng 上下文)。
http://www.dropwizard.io/0.9.2/docs/about/release-notes.html
我的 dropwizard 应用程序有一个集成测试,我在其中使用休眠 h2 数据库来存储数据。对于测试的第二部分,我使用 jersey-testframework 来处理资源和休息调用。
为了使这两个部分协同工作,我必须为每个案例创建一个 TestRule。
休眠:
@ClassRule
public static final SessionFactoryRule sessionFactoryRule = new SessionFactoryRule(User.class, HibernateUtil.getHibernateClasses());
public static final ProgramDAO programDao = new ProgramDAO(sessionFactoryRule.getSessionFactory());
球衣:
@ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addProvider(new AuthDynamicFeature(
new OAuthCredentialAuthFilter.Builder<User>()
.setAuthenticator(new OAuthAuthenticator(userManagement))
.setAuthorizer(new OAuthAuthorizer())
.setPrefix(TOKEN_TYPE)
.buildAuthFilter()))
.addProvider(new AuthValueFactoryProvider.Binder<>(User.class))
.addProvider(RolesAllowedDynamicFeature.class)
.addResource(new AdResource(urlMapperMock, programDao))
.build();
h2 hibernate db 配置
Configuration configuration = new Configuration()
.setInterceptor(new SoftDeleteInterceptor())
.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect")
.setProperty("hibernate.connection.driver_class", "org.h2.Driver")
.setProperty("hibernate.connection.url", "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")
.setProperty("hibernate.hbm2ddl.auto", "create")
.setProperty("hibernate.default_batch_fetch_size", "200")
.setProperty("hibernate.show_sql", "false")
.setProperty("hibernate.current_session_context_class", "thread");
现在,当我在资源上调用 请求 时...
@Test
public void resourceCheck() {
javax.ws.rs.core.Response response = resources.getJerseyTest().target(Ad.TABLE_NAME).request().header(HEADER_KEY_AUTHORIZATION, HEADER_VALUE_VALID_BEARER_TOKEN).get();
assertThat(response.getStatus()).isEqualTo(200);
}
...抛出如下错误
ERROR [2016-01-26 11:23:21,594] org.glassfish.grizzly.servlet.ServletHandler: service exception:
! org.hibernate.HibernateException: getNamedQuery is not valid without active transaction
! at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
! at com.sun.proxy.$Proxy74.getNamedQuery(Unknown Source) ~[na:na]
! at io.dropwizard.hibernate.AbstractDAO.namedQuery(AbstractDAO.java:57) ~[dropwizard-hibernate-0.9.1.jar:0.9.1]
! at com.ad4mat.api.db.core.AdDAO.findAllByUser(AdDAO.java:36) ~[classes/:na]
! at com.ad4mat.api.resource.AdResource.getAll(AdResource.java:79) ~[classes/:na]
显然没有针对测试用例的事务处理,但应该有一个。
我的普通 dropwizard 应用程序运行良好。通过使用 @UnitOfWork
.
当我在 dao 中添加一个手动事务时...
public List<Ad> findAllByUser(User user) {
currentSession().beginTransaction();
Query query = namedQuery("ad.findAllByUser")
.setParameter(User.FOREIGN_COLUMN_ID, user.getId());
return query.list();
集成测试有效,但我的应用程序会抛出嵌套事务异常。
所以我的问题是:
如何使@UnitOfWork 注释可用于集成测试过程。显然缺少事务处理实现。我必须 jersey.register()
Dropwizard-Hibernate 的某个组件吗?
从 dropwizard 版本 0.9.2 开始,可以在 Jersey 上下文之外使用 @UnitOfWork 注释。 也许您正在寻找 dropwizard 更新;那么您应该能够在任何上下文中执行数据库操作(最重要的是 junit/testng 上下文)。 http://www.dropwizard.io/0.9.2/docs/about/release-notes.html