I'm trying to write a Unit Test for a simple bean that's used in my program to validate forms. The bean is annotated with @Component
and has a class variable that is initialized using
@Value("${this.property.value}") private String thisProperty;
I would like to write unit tests for the validation methods inside this class, however, if possible I would like to do so without utilizing the properties file. My reasoning behind this, is that if the value I'm pulling from the properties file changes, I would like that to not affect my test case. My test case is testing the code that validates the value, not the value itself.
Is there a way to use Java code inside my test class to initialize a Java class and populate the Spring @Value property inside that class then use that to test with?
I did find this How To that seems to be close, but still uses a properties file. I would rather it all be Java code.
@Value spring boot annotation is used to inject values from the properties file into the java variables that have been configured. The @Value annotation in spring boot is used to assign values to variables and method parameters from properties files or system environments.
Spring @Value annotation is used to assign default values to variables and method arguments. We can read spring environment variables as well as system variables using @Value annotation.
For the record, the specification of what a POJO is, means that the class cannot contain pre-specified annotations. So even in another world where @Value could work on a non-spring bean, it would still, by definition, break the POJO aspect of the class.
no :) you can use annotations to annotate classes, fields, methods and their arguments. but not in methods, since there is no way, to get method- local variables using reflection in order to process these annotations. Use @Value in your field, and read the value from your method.
If possible I would try to write those test without Spring Context. If you create this class in your test without spring, then you have full control over its fields.
To set the @value
field you can use Springs ReflectionTestUtils
- it has a method setField
to set private fields.
@see JavaDoc: ReflectionTestUtils.setField(java.lang.Object, java.lang.String, java.lang.Object)
Since Spring 4.1 you could set up property values just in code by using org.springframework.test.context.TestPropertySource
annotation on Unit Tests class level. You could use this approach even for injecting properties into dependent bean instances
For example
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = FooTest.Config.class) @TestPropertySource(properties = { "some.bar.value=testValue", }) public class FooTest { @Value("${some.bar.value}") String bar; @Test public void testValueSetup() { assertEquals("testValue", bar); } @Configuration static class Config { @Bean public static PropertySourcesPlaceholderConfigurer propertiesResolver() { return new PropertySourcesPlaceholderConfigurer(); } } }
Note: It's necessary to have instance of org.springframework.context.support.PropertySourcesPlaceholderConfigurer
in Spring context
Edit 24-08-2017: If you are using SpringBoot 1.4.0 and later you could initialize tests with @SpringBootTest
and @SpringBootConfiguration
annotations. More info here
In case of SpringBoot we have following code
@SpringBootTest @SpringBootConfiguration @RunWith(SpringJUnit4ClassRunner.class) @TestPropertySource(properties = { "some.bar.value=testValue", }) public class FooTest { @Value("${some.bar.value}") String bar; @Test public void testValueSetup() { assertEquals("testValue", bar); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With