I'm trying to test my LoginCacheServiceImpl but having problems. I followed this tutorial http://crunchify.com/how-to-create-a-simple-in-memory-cache-in-java-lightweight-cache/ and called it InMemoryCache with my own model object LoginEvent.
@Service
@PropertySource("classpath:app.properties")
public class LoginCacheServiceImpl {
@Value("$app{timeToLive}")
private long timeToLive;
@Value("$app{timerInterval}")
private long timerInterval;
private InMemoryCache<String, LoginEvent> cache;
@Override
public InMemoryCache<String, LoginEvent> getCache() {
return cache;
}
@PostConstruct
public void init() {
cache = new InMemoryCache<>(timeToLive, timerInterval, 10000);
}
}
The code runs fine but I'm trying to write unit tests for it. In the test class:
@TestPropertySource("classpath:app-test.properties")
@ContextConfiguration(classes = { LoginCacheServiceImplTest.class, LoginCacheServiceImpl.class })
@RunWith(SpringJUnit4ClassRunner.class)
public class LoginCacheServiceImplTest
@Autowired
private Environment environment;
private LoginCacheServiceImpl cacheService;
@Before
public void setUp() {
String test = environment.getProperty("timeToLive"); // this value gets parsed correctly
cacheService = new LoginCacheServiceImpl();
}
@Test
public void doNothing() {
System.out.println("test");
}
}
I get the error:
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'long'; nested exception is java.lang.NumberFormatException: For input string: "$app{timeToLive}"
at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:77)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:54)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:968)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 42 more
Caused by: java.lang.NumberFormatException: For input string: "$app{timeToLive}"
I'm not sure how I should either rewrite my LoginCacheServiceImpl to make it testable, or preferably, to set up my test class so PostConstruct parses the timeToLive and timerInterval properly.
app-test.properties:
timeToLive=1000
timerInterval=1000
As an aside, I'm using Mockito 2.X. Can you use both MockitoJUnitRunner and SpringJUnit4ClassRunner? If not, how do you choose which one to use (sorry, new to Java).
Edit: If I have this line
@ContextConfiguration(classes = { LoginCacheServiceImplTest.class, LoginCacheServiceImpl.class })
the unit test gives me that numbeformatexception error when I try to run the test as it is trying to create LoginCacheServiceImpl. But if I change it to
@ContextConfiguration(classes = { LoginCacheServiceImplTest.class })
and just do
String prop = environment.getProperty("timeToLive");
where in my app-test.properties file has
timeToLive=1000
the unit test can read that properties file. The timeToLive=1000
is a different number than I have in the original app.properties file so I do not think it's an issue of finding the app-test.properties file.