Background Info
I have a thread. It's a dedicated thread to continuously take out a task from a queue and write to a persistent repository. So it's code is like this.
public class Processor extends Thread {
//Context saves reference to the task queue and the write backEnd service
public GeneralProcessor(Context context){initProcessor( context, Type.GENERAL);}
public void run() {
...
synchronized (Processor.class) {
Thread curThread=currentThread();
Context context=getContext();
ConcurrentLinkedQueue<Task> taskQue =context.getTasks();
if (taskQue.size() > 0) {
Task t = taskQue.poll();
Transaction ts = new Transaction();
//all works to copy Task's member values to Transaction, and add other values to this transaction
//...
context.getService().save(ts);//this is the line I want to monitor. This is also related to issue in some way.
}
}
}
}
The Issue
But there is an issue when I wrote a unit test for this class. My original unit test is this.
@ExtendWith(MockitoExtension.class)
public class GeneralProcessorTest {
@InjectMocks
private GeneralProcessor generalProcessor;
@Mock
private Context context;
@Spy
private ConcurrentLinkedQueue<Task> tasks;
@Mock
private TransactionRepository transactionRepository;
@Captor
private ArgumentCaptor<Transaction> transactionArgumentCaptor;
@Mock
private TransactionService transactionService;
@BeforeEach
void setup() {
//transactionService=new TransactionServiceImpl(transactionRepository);
}
@Test
@SneakyThrows
void should_match_save_times_single_thread() {
//given
CountDownLatch latch=new CountDownLatch(0);
this.tasks.add(new Task(10));
//stub code
when(context.getTasks()).thenReturn(tasks);
when(context.getService()).thenReturn(transactionService);
//when
generalProcessor.start();
latch.await(1, TimeUnit.SECONDS);
//then
//the issue happened here!
verify(transactionService).save(transactionArgumentCaptor.capture());
List<Transaction> capturedArguments = transactionArgumentCaptor.getAllValues();
assertEquals(capturedArguments.size(),1);
}
But I got:
Wanted but not invoked:
transactionService.save(
<Capturing argument>
);
at com.example.demo.GeneralProcessorTest.should_match_save_times_single_thread(GeneralProcessorTest.java:65)
Actually, there were zero interactions with this mock.
In fact, I tried to init transactionService with new. But Mockito told me that in verify I can only use Mock object.
So I am confused. Is there any way to let me use verify while at the same time keep transactionService working as a normal object? Any info is appreciated.