JPA Hibernate Maven testing -- unknown class
You are running the code from your own main method, which I am guessing means it isn't being run by maven. The code in test is not included as part of the artifact generated by maven, it is only included during mavens test phase for running unit tests.
If you are using maven, why not simply create JUnit tests that maven will run as part of the build process instead of rolling your own.
How to instruct Maven to ignore my main/resources/persistence.xml in favor of test/...?
Check out the alternate descriptors functionality which is aimed at what you're trying to do.
Try this setup:
src/main/resources/META-INF/persistence.xml
src/main/resources/META-INF/test.persistence.xml
Then you can construct OpenEJB to prefer the test.persistence.xml
file by setting the openejb.altdd.prefix
System or InitialContext property to test
A different possible solution could be to override the persistence unit properties in the test. With that approach you could avoid the need for a second persistence.xml
which can be nice as maintaining two can be a pain.
You can use the Maven approach, but be aware that per spec the persistence provider will only look (aka scan) for @Entity
beans in the exact jar or directory where the persistence.xml
is found. So be keenly aware that in Maven these are two different locations:
target/classes
target/test-classes
EDIT More details on the overriding capabilities
You can override any property in your test setup via either system properties or the initial context properties (this includes jndi.properties files). The format is:
<unit-name>.<property>=<value>
So for example with the following persistence.xml
:
<persistence>
<persistence-unit name="movie-unit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>movieDatabase</jta-data-source>
<non-jta-data-source>movieDatabaseUnmanaged</non-jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.max_fetch_depth" value="3"/>
</properties>
</persistence-unit>
</persistence>
You can override and add persistence unit properties in your test case. There are currently no facilities for removing them (if you have a need for that let us know – it hasn't really come up so far).
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,"org.apache.openejb.client.LocalInitialContextFactory");
p.put("movie-unit.hibernate.hbm2ddl.auto", "update");
p.put("movie-unit.hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
context = new InitialContext(p);
Or alternatively via a jndi.properties
file
java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory
movie-unit.hibernate.hbm2ddl.auto = update
movie-unit.hibernate.dialect = org.hibernate.dialect.HSQLDialect
No autodetection of JPA Entities in maven-verify
By default autodetection works for entities in the same classpath item as persistence.xml
. It can be configured by <jar-file>
elements.
To enable correct autodetection when persistence.xml
is in src/test/resources/META-INF
I use the following trick:
persistence.xml
:
<persistence ...>
<persistence-unit ...>
<jar-file>${project.build.outputDirectory}</jar-file>
...
</persistence-unit>
</persistence>
pom.xml
- enable resource filtering for src/test/resources
:
<project ...>
...
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
</build>
</project>
Though I'm not sure how to use it if your persistence.xml
is actually in src/test/META-INF
.
Spring Boot maven multimodule project - unit testing (application context)
After reading various articles and posts eg. Is it OK to use SpringRunner in unit tests? I realized that I don't need the entire application context when running tests, instead I should mock bean dependencies using plain @Mock
annotation if testing without even involving and loading spring application context (which is faster). However, If I need some slice of application context (eg. to automatically load test properties or just for integration tests)
then I use spring boot annotations prepared for that: @WebMvcTest
@JpaTest
@SpringBootTest
and so on.
Examples:
Plain Mock Test (without involving spring):
public class UserServiceImplTest {
@Mock
private UserRepository userRepository;
private UserServiceImpl userService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
userService = new UserServiceImpl(userRepository);
}
/* Some tests here */
}
Test with slice of spring context:
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@EnableConfigurationProperties(value = DecisionProposalProperties.class)
@SpringBootTest(classes = {
DecisionProposalRepositoryService.class,
DecisionProposalMapperImpl.class
})
public class DecisionProposalRepositoryServiceTest {
@MockBean
private DecisionProposalRepository decisionProposalRepository;
@MockBean
private CommentRepository commentRepository;
@Autowired
private DecisionProposalRepositoryService decisionProposalRepositoryService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
/* Some tests here */
}
Data jpa test:
@RunWith(SpringRunner.class)
@DataJpaTest
public class ImageProposalRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private ImageProposalRepository imageProposalRepository;
@Test
public void testFindOne() throws Exception {
ImageProposal imageProposal = ImageProposal.builder()
.size(1024)
.filePath("/test/file/path").build();
entityManager.persist(imageProposal);
ImageProposal foundImageProposal = imageProposalRepository.findOne(imageProposal.getId());
assertThat(foundImageProposal).isEqualTo(imageProposal);
}
}
How to test Maven module project with Spring Boot
I think context tests should be available per module so you can find issues with wire and configuration early on and not depend on your full application tests to find them.
I worked around this issue with a test application class in the same module.
Make sure this main class is in your test dir.
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
your context should work now.
@RunWith(SpringRunner.class)
@ActiveProfiles(profiles = {Profiles.WEB_REST})
@WebMvcTest(EntityController.class)
@DirtiesContext
public class ServicesControllerTest {
@Autowired
private MockMvc mvc;
@MockBean
private Controller controller;
@Test
public void testAll() throws Exception {
given(controller.process(null)).willReturn(null);
mvc.perform(get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
}
Related Topics
Variable Naming Conventions in Java
Jtable Won't Show Column Headers
Running a Java Program from Another Java Program
Jpanel Positions and Sizes Changes According to Screensize
How to Read Input Character-By-Character in Java
Convert Epoch Seconds to Date and Time Format in Java
Change Location of Log4J.Properties
Jersey Maven Quickstart Archetype in Eclipse
Package a Non-Modular Javafx Application
How to Draw a Tree Representing a Graph of Connected Nodes
Find Place for Dedicated Application Folder
Java.Lang.Stackoverflowerror While Using a Regex to Parse Big Strings
How to Insert a Character in a String at a Certain Position
Adding Chartpanel to Jtabbedpane Using JPAnel
What Are the Differences Between Abstract Classes and Interfaces in Java 8
Using Javamail to Connect to Gmail Smtp Server Ignores Specified Port and Tries to Use 25