Issue
I'm writing JUnit test for this method processData
- I'm doing @Autowired
Cache mycache
in Junit, and mocking Cache mycache
under my Test method. When I'm doing this mycache = mock(Cache.class)
- this returns some object in Junit method but when I invoke my actual method from Junit Cache mycache
going as null in Main
class. Please find the code below:
What I'm missing here - how to resolve this NullPointer exception issue - why mycache is going as null when actual method triggered from Junit - though I've mocked this object. Any help would be really appreciated. Thank you!
Main.Java
import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Main {
@Autowired
Cache mycache;
public Product processData(String productId) {
System.out.println("productId value: " +productId);
System.out.println("mycache value: " +mycache);
Product product = (Product) mycache.getIfPresent(productId); //getting NullPointer exception here
if (product != null) {
return product;
}
// do some processing
return product;
}
}
MainTest.Java
public class MainTest {
@Autowired
Cache mycache;
@Test
public void processDataTest() throws Exception {
Main main = new Main();
mycache = mock(Cache.class);
System.out.println("mycache: " + mycache.toString()); // Mock for Cache, hashCode: 3244883
when(mycache.getIfPresent("9393939")).thenReturn(null);
Product product = main.processData("9393939");
assertNotNull(product);
}
}
Exception Log trace:
mycache: Mock for Cache, hashCode: 3244883
productId value: 9393939
mycache value: null
java.lang.NullPointerException
at com.test.processData(Main.java:122)
at com.test.MainTest.processDataTest(MainTest.java:161)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
Solution
Instead of doing:
@Component
public class Main {
@Autowired
Cache mycache;
...
Inject it via a constructor:
@Component
public class Main {
private final Cache mycache;
public Main(Cache mycache) {
this.mycache = mycache;
}
}
Now it your test you can create an instance of Main
where you can provide a mock of Cache
.
Answered By - Eugene
Answer Checked By - Robin (JavaFixing Admin)