Sushant
Sushant

Reputation: 1

@Value config injection failing

I am trying to run a spring JUnit test case using - @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "classpath:some.xml" })

The xml has bean defined along with in memory db details

<bean id="orderService" class="com.example.OrderServiceImpl">
        <!-- set properties, etc. -->
    </bean>

I am doing @Value injection inside the bean class OrderServiceImpl, but it does not happen while executing the test case but the same runs fine when I run the application. Can you please help ?

Upvotes: 0

Views: 619

Answers (2)

Hank D
Hank D

Reputation: 6471

Check to see if a some.xml exists in both main and test trees. If it exists in both, the one in the test tree should override the one in the main branch.

Make sure the some.xml you are actually loading has a property-placeholder, such as

<context:property-placeholder location="classpath:some.properties"/>

I realize that there are more modern ways to manage properties, but this is simple and easy to specify for unit tests.

I find that multiple tests become very awkward with config files on the classpath, so I like to take advantage of a feature of the @ContextConfiguration that lets me create a dedicated minimal config for each test. The way it works is that for each test class, by convention, it can look for a config file in the same relative directory path as your test class package, and named after your test case. That way you can completely control the config and properties for each test case. You might try it--it can eliminate confusion caused by shared config files. To do it, remove the value in the@ContextConfiguration. Then, say you have a test case com.myCompany.SomeTest located in src/test/java/com/myCompany/. Create a file called SomeTest-context.xml in directory src/test/resources/com/myCompany and put the minimal config you need for that unit in the file. @ContextConfiguration will, by convention, find the config file of that name in that location and use it for your test. Although not part of the conventions I just spoke of, I put a properties file for each test in the same directory with just the properties I need for that test, named after the test case as well (e.g. SomeTest.properties). In your test case-specific context, add a property-placeholder line like this to get your test-specific properties:

<context:property-placeholder location="classpath:com/myCompany/SomeTest.properties"/>

At the top of your test case, you would put

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration                        // no parameters
public class FileEncryptionUtilsTest { ...

If you do that, you'll be able to inject beans and values to your heart's content, without worrying about side-effects of things being added to a shared context or dealing with errors arising from multiple context files with the same name.

The key advantage is that you are testing a unit here, not the integration represented by an application context file. If you share an application context file in your unit tests, you're testing the application context along with your bean, and that's more of an integration test goal, not a unit test need.

Upvotes: 0

Pablo Gra&#241;a
Pablo Gra&#241;a

Reputation: 11

You need to add a PropertySourcesPlaceholderConfigurer or PropertyPlaceholderConfigurer to your test context. This SO question may give you a hint: Populating Spring @Value during Unit Test.

Upvotes: 1

Related Questions