Reputation: 3382
I am using spring @Value
annotation and setting values for some fields in class A
.
I am writing unit tests for this class A
. In the test class, I am annotating the reference for class A
with Mockito @Spy
. I am setting the values as system properties and then invoking MockitoAnnotations.initMocks(this).
My expectation is the spied object will have the fields initialized with the values from system properties via @Value
annotation. But this is not happening.
Please anybody could explain?
Upvotes: 3
Views: 9791
Reputation: 42283
Mockito is not Spring aware! And will never be! You'll always have to init these kind of injection yourself as it is not pure java.
However you can take a look at springockito, it is a spring extension that enable some interesting usage of Mockito with Spring. But you'll have to create a Spring context for the test.
Note that using a spring context in a JUnit test is like crafting an integration test.
Upvotes: 3
Reputation: 23913
I have a similar test and I'm using the following relevant code:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="/context.xml")
public class ContextTest {
private boolean started = false;
@Spy
@Autowired
private Baz baz;
@Before
public void before() {
if (!started) {
MockitoAnnotations.initMocks(this);
started = true;
}
}
@Test
public void spy() {
Assert.assertEquals("value", baz.getProperty());
Mockito.verify(baz).getProperty();
}
}
Basically it will let spring process the test annotations (due to SpringJUnitRunner
) and afterwards let Mockito process them (explicitly invoked MockitoAnnotations.initMocks(instanceOfTestClass)
).
Other files to have a complete test
simple Baz.java
spring class:
package foo.bar;
import org.springframework.beans.factory.annotation.Value;
public class Baz {
@Value("${property:test}")
private String property;
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
}
the context.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>my.properties</value>
</property>
</bean>
<bean id="baz" class="foo.bar.Baz" />
</beans>
my.property
file:
property=value
and the maven (pom.xml
) file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>spring-test</groupId>
<artifactId>my.spring.test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
the file structure is:
+ spring-test
- pom.xml
+ src/main/java
+ foo.bar
- Baz.java
+ src/main/resources
- context.xml
- my.properties
+ src/test/java
+ foo.bar
- ContextTest.java
Upvotes: 3