Browse Source

Document AOT workaround for @⁠PersistenceContext & @⁠PersistenceUnit in tests

Although @⁠PersistenceContext and @⁠PersistenceUnit are still not
supported in tests running in AOT mode, as of Spring Framework 7.0,
developers can inject an EntityManager or EntityManagerFactory into
tests using @⁠Autowired instead of @⁠PersistenceContext and
@⁠PersistenceUnit, respectively.

See commit 096303c477
See gh-33414
Closes gh-31442
pull/35768/head
Sam Brannen 1 month ago
parent
commit
934394eb2a
  1. 10
      framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc
  2. 4
      spring-test/src/test/java/org/springframework/test/context/aot/AotIntegrationTests.java
  3. 4
      spring-test/src/test/java/org/springframework/test/context/testng/transaction/ejb/AbstractEjbTxDaoTestNGTests.java
  4. 10
      spring-test/src/test/java/org/springframework/test/context/transaction/ejb/AbstractEjbTxDaoTests.java

10
framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc

@ -43,6 +43,16 @@ alternative, you can set the same property via the
xref:appendix.adoc#appendix-spring-properties[`SpringProperties`] mechanism. xref:appendix.adoc#appendix-spring-properties[`SpringProperties`] mechanism.
==== ====
[TIP]
====
JPA's `@PersistenceContext` and `@PersistenceUnit` annotations cannot be used to perform
dependency injection within test classes in AOT mode.
However, as of Spring Framework 7.0, you can inject an `EntityManager` or
`EntityManagerFactory` into tests using `@Autowired` instead of `@PersistenceContext` and
`@PersistenceUnit`, respectively.
====
[NOTE] [NOTE]
==== ====
The `@ContextHierarchy` annotation is not supported in AOT mode. The `@ContextHierarchy` annotation is not supported in AOT mode.

4
spring-test/src/test/java/org/springframework/test/context/aot/AotIntegrationTests.java

@ -147,7 +147,9 @@ class AotIntegrationTests extends AbstractAotTests {
// We only include test classes named *Tests so that we don't pick up // We only include test classes named *Tests so that we don't pick up
// internal TestCase classes that aren't really tests. // internal TestCase classes that aren't really tests.
.filter(clazz -> clazz.getSimpleName().endsWith("Tests")) .filter(clazz -> clazz.getSimpleName().endsWith("Tests"))
// TestNG EJB tests use @PersistenceContext which is not yet supported in tests in AOT mode. // TestNG EJB tests use @EJB which is not supported in tests in AOT mode, and
// since @DisabledInAotMode is not able to disable TestNG tests at runtime,
// we have to filter out those tests here.
.filter(clazz -> !clazz.getPackageName().contains("testng.transaction.ejb")) .filter(clazz -> !clazz.getPackageName().contains("testng.transaction.ejb"))
// AOT processing works for ParameterizedDependencyInjectionTests by itself // AOT processing works for ParameterizedDependencyInjectionTests by itself
// but fails for an unknown reason within the entire spring-test module. // but fails for an unknown reason within the entire spring-test module.

4
spring-test/src/test/java/org/springframework/test/context/testng/transaction/ejb/AbstractEjbTxDaoTestNGTests.java

@ -18,10 +18,10 @@ package org.springframework.test.context.testng.transaction.ejb;
import jakarta.ejb.EJB; import jakarta.ejb.EJB;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests;
@ -45,7 +45,7 @@ abstract class AbstractEjbTxDaoTestNGTests extends AbstractTransactionalTestNGSp
@EJB @EJB
protected TestEntityDao dao; protected TestEntityDao dao;
@PersistenceContext @Autowired
protected EntityManager em; protected EntityManager em;

10
spring-test/src/test/java/org/springframework/test/context/transaction/ejb/AbstractEjbTxDaoTests.java

@ -18,12 +18,13 @@ package org.springframework.test.context.transaction.ejb;
import jakarta.ejb.EJB; import jakarta.ejb.EJB;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext; import jakarta.persistence.EntityManagerFactory;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@ -51,9 +52,14 @@ abstract class AbstractEjbTxDaoTests {
@EJB @EJB
protected TestEntityDao dao; protected TestEntityDao dao;
@PersistenceContext @Autowired
protected EntityManager em; protected EntityManager em;
// The EntityManagerFactory is not actually used by tests. We only declare it
// to ensure that dependency injection works for it.
@Autowired
protected EntityManagerFactory emf;
@Test @Test
void test1InitialState() { void test1InitialState() {

Loading…
Cancel
Save