Reputation: 416
I have an interface
@Repository
public interface WorkJobRepository extends JpaRepository<WorkJob, Long> {
WorkJob findById(String id);
}
This extends JpaRepository
.
Now from some other class ReadWorkJob
public class ReadWorkJob implements WorkJob {
@Autowired
private WorkJobRepository;
public void writeNewIdData(JSONObject jsonObject) {
WorkJob workJob = getExistingId(jsonObject.get("id").toString());
}
private WorkJob getExistingId(String id) {
logger.info("check point ppppp");
WorkJob workJob = workJobRepository.findById(id);
logger.info("check point qqqqq");
return workJob != null ? workJob : new WorkJob();
}
}
I am calling this like
workJobRepository.findById(id);
now I want to test the methods in class ReadWorkJob
and to do that i want to mock the call to workJobRepository
and want it to return null.
@RunWith(MockitoJUnitRunner.class)
public class ReadWorkJobTest {
private static final String RIGHT_DATA_FILE_NAME = "test.txt";
@InjectMocks
private ReadWorkJob readWorkJob;
private WorkJobRepository workJobRepository;
@Before
public void setUp() throws Exception {
workJobRepository = Mockito.mock(WorkJobRepository.class);
when(workJobRepository.findById(any())).thenReturn(null);
logger.info("check point test case setup");
}
@Test
public void testNewIdDBWriter() throws Exception {
logger.info("check point test case 1");
// In here i am not asserting anything i just want the method call to succeed first
readWorkJob.writeNewIdData(getRightData());
logger.info(("check point test case 2"));
}
private JSONObject getRightData() throws IOException {
String rightDataString = new String(Files.readAllBytes(Paths.get(RIGHT_DATA_FILE_NAME)));
JSONObject jsonObject = new JSONObject(rightDataString);
return jsonObject;
}
}
but the mock is not working.
The test execution is not coming till the "check point qqqqq". I think that it's still trying to call the db.
Stack trace
java.lang.NullPointerException
16:42:31.387 [DEBUG] [TestEventLogger] at
com.shiv.work.job.ReadWorkJob.getExistingId(ReadWorkJob.java:102)
16:42:31.387 [DEBUG] [TestEventLogger] at
com.shiv.work.job.ReadWorkJob.writeNewIdDataTo(ReadWorkJob.java:71)
16:42:31.387 [DEBUG] [TestEventLogger] at com.shiv.work.job.ReadWorkJobTest.testNewIdDBWriter(ReadWorkJobTest.java:45)
16:42:31.387 [DEBUG] [TestEventLogger] at
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
16:42:31.387 [DEBUG] [TestEventLogger] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
16:42:31.387 [DEBUG] [TestEventLogger] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
16:42:31.387 [DEBUG] [TestEventLogger] at java.base/java.lang.reflect.Method.invoke(Method.java:567)
16:42:31.387 [DEBUG] [TestEventLogger] at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
16:42:31.387 [DEBUG] [TestEventLogger] at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
16:42:31.387 [DEBUG] [TestEventLogger] at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
16:42:31.387 [DEBUG] [TestEventLogger] at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
16:42:31.387 [DEBUG] [TestEventLogger] at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
16:42:31.387 [DEBUG] [TestEventLogger] at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
16:42:31.388 [DEBUG] [TestEventLogger] at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
16:42:31.388 [DEBUG] [TestEventLogger] at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
16:42:31.388 [DEBUG] [TestEventLogger] at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
16:42:31.388 [DEBUG] [TestEventLogger] at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
16:42:31.388 [DEBUG] [TestEventLogger] at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
16:42:31.388 [DEBUG] [TestEventLogger] at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
16:42:31.388 [DEBUG] [TestEventLogger] at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
16:42:31.388 [DEBUG] [TestEventLogger] at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
16:42:31.388 [DEBUG] [TestEventLogger] at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
16:42:31.388 [DEBUG] [TestEventLogger] at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
16:42:31.388 [DEBUG] [TestEventLogger] at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
16:42:31.388 [DEBUG] [TestEventLogger] at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
16:42:31.388 [DEBUG] [TestEventLogger] at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
16:42:31.388 [DEBUG] [TestEventLogger] at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
16:42:31.388 [DEBUG] [TestEventLogger] at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
16:42:31.388 [DEBUG] [TestEventLogger] at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
16:42:31.388 [DEBUG] [TestEventLogger] at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
16:42:31.388 [DEBUG] [TestEventLogger] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
16:42:31.388 [DEBUG] [TestEventLogger] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
16:42:31.388 [DEBUG] [TestEventLogger] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
16:42:31.389 [DEBUG] [TestEventLogger] at java.base/java.lang.reflect.Method.invoke(Method.java:567)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
16:42:31.389 [DEBUG] [TestEventLogger] at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
16:42:31.389 [DEBUG] [TestEventLogger] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
16:42:31.389 [DEBUG] [TestEventLogger] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
16:42:31.389 [DEBUG] [TestEventLogger] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
16:42:31.389 [DEBUG] [TestEventLogger] at java.base/java.lang.reflect.Method.invoke(Method.java:567)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
16:42:31.389 [DEBUG] [TestEventLogger] at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
16:42:31.389 [DEBUG] [TestEventLogger] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
16:42:31.389 [DEBUG] [TestEventLogger] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
16:42:31.390 [DEBUG] [TestEventLogger] at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
16:42:31.390 [DEBUG] [TestEventLogger] at java.base/java.lang.Thread.run(Thread.java:830)
Upvotes: 1
Views: 1254
Reputation: 247143
From the shown test code, the manually created repository is not being injected into the subject under test, which is why it is null and causing the NPE
Since using @Autowired
you would also need to make sure the dependency is properly tagged to be mocked
@Mock
private WorkJobRepository workJobRepository;
@InjectMocks
private ReadWorkJob readWorkJob;
@Before
public void setUp() throws Exception {
when(workJobRepository.findById(any())).thenReturn(null);
logger.info("check point test case setup");
}
With that done the test should behave as expected.
When the dependency was created manually, it would not being injected into the subject under test.
Another approach would be to have the subject class follow explicit dependency principle
public class ReadWorkJob {
private WorkJobRepository workJobRepository;
@Autowired
public ReadWorkJob (WorkJobRepository workJobRepository) {
this.workJobRepository = workJobRepository;
}
public void writeNewIdData(JSONObject jsonObject) {
WorkJob workJob = getExistingId(jsonObject.get("id").toString());
}
private WorkJob getExistingId(String id) {
logger.info("check point ppppp");
WorkJob workJob = workJobRepository.findById(id);
logger.info("check point qqqqq");
return workJob != null ? workJob : new WorkJob();
}
}
And refactor the test accordingly
@RunWith(MockitoJUnitRunner.class)
public class ReadWorkJobTest {
private static final String RIGHT_DATA_FILE_NAME = "test.txt";
private ReadWorkJob readWorkJob;
private WorkJobRepository workJobRepository;
@Before
public void setUp() throws Exception {
workJobRepository = Mockito.mock(WorkJobRepository.class);
when(workJobRepository.findById(any())).thenReturn(null);
readWorkJob = new ReadWorkJob(workJobRepository); //<--
logger.info("check point test case setup");
}
@Test
public void testNewIdDBWriter() throws Exception {
logger.info("check point test case 1");
readWorkJob.writeNewIdData(getRightData());
logger.info(("check point test case 2"));
}
private JSONObject getRightData() throws IOException {
String rightDataString = new String(Files.readAllBytes(Paths.get(RIGHT_DATA_FILE_NAME)));
JSONObject jsonObject = new JSONObject(rightDataString);
return jsonObject;
}
}
Upvotes: 1