Spring jUnit Testing - either can not autowire or can not find appContext.xml
-
14-02-2021 - |
Question
I am unittesting a spring based application atm. First the problem is, that if I haven't started the app once on a server the unittests all fail. If I do start the app on the server first (and stop it), my unit tests are working.
Without starting the server I get the following error:
... java.io.FileNotFoundException: class path resource [META-INF/spring/applicationContext-test.xml] cannot be opened because it does not exist
My Unit test is defined as following:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/META-INF/spring/applicationContext-test.xml" })
@TransactionConfiguration
@Transactional
public class InventoryControllerTest extends AbstractTransactionalJUnit4SpringContextTests {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private AnnotationMethodHandlerAdapter handlerAdapter;
@Before
public void setUp() throws Exception {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
handlerAdapter = applicationContext
.getBean(AnnotationMethodHandlerAdapter.class);
}
//... tests
}
So like I said, if I've started the app once before, everything works fine.
So I changed the configuration location to locations = { "classpath/META-INF/spring/applicationContext-test.xml" }) But without effort, same exception as named above.
The only way to get further is this location: locations = { "classpath*:applicationContext-test.xml" }) Then I get this exception: No matching bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
But that's confusing, because I definetly have a datasource in my test context file:
<bean class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" id="dataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:testdb;sql.syntax_ora=true" />
<property name="username" value="some" />
<property name="password" value="some" />
</bean>
EIDT 2
After recognizing, that the problem is RunWith(...) and extending the spring class at the same time and removing all wildcards from the location path. I get this exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [META-INF/spring/applicationContext-test.xml]: Cannot resolve reference to bean 'entityManagerFactory' while setting bean property 'entityManagerFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/spring/applicationContext-test.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No persistence unit with name 'persistenceUnitTest' found
... 24 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/spring/applicationContext-test.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No persistence unit with name 'persistenceUnitTest' found
... 40 more
Caused by: java.lang.IllegalArgumentException: No persistence unit with name 'persistenceUnitTest' found)
... 47 more
I would really appreciate any help!
Thanks in advance
Solution
There must be a :
between classpath
and Path, as well as the path must not start with /
. So the correct syntax would be:
@ContextConfiguration(locations = { "classpath:META-INF/spring/applicationContext-test.xml" })
or a bit shorter form
@ContextConfiguration("classpath:META-INF/spring/applicationContext-test.xml")
An other problem, found by your self is that you should use @ContextConfiguration
OR AbstractTransactionalJUnit4SpringContextTests
. Here is the accoding note from Java Doc of AbstractTransactonalJUnit4SpringContextTests
> Note: this class serves only as a convenience for extension. If you do not wish for your test classes to be tied to a Spring-specific class hierarchy, you may configure your own custom test classes by using {@link SpringJUnit4ClassRunner}, {@link ContextConfiguration @ContextConfiguration}, {@link TestExecutionListeners @TestExecutionListeners}, {@link Transactional @Transactional}, etc.
The starting problem:
Eclipse does not copy the resources from src\test\resources
to the target directory. So you need one tool or something that do this for you. You have found one way: starting the application. A second one would be running maven test
from eclipse.