Al Phaba
Al Phaba

Reputation: 6755

Spring Boot Integration Test with awaitility and @SpyBean not working, because @SpyBean is always null

I want to test my scheduled task, so I followed this tutorial

@SpringJUnitConfig(SchedulerConfig.class)
public class MailJobFinderTaskIT {

    @SpyBean
    private MailJobFinderTask mailJobFinderTask;

    @Test
    public void whenWaitThreeSecond_ThenTaskCalledThreeTimes(){
        await()
            .atMost(Duration.ofSeconds(3))
            .untilAsserted(() -> verify(mailJobFinderTask, atLeast(3)).findEmailJobs());
    }

}

But actually it does not work, because the the following error

 org.mockito.exceptions.misusing.NullInsteadOfMockException:
        Argument passed to verify() should be a mock but is null!
        Examples of correct verifications:
        verify(mock).someMethod();
        verify(mock, times(10)).someMethod();
        verify(mock, atLeastOnce()).someMethod();
        not: verify(mock.someMethod());
        Also, if you use @Mock annotation don't miss initMocks()

here is the signature of my Task-Class

@Component
public class MailJobFinderTask extends SuppressedLogPoller {
....
}

 @Scheduled(fixedRate = 1000)
 public void findEmailJobs() {
 .
 .
 }

I tried already to change the Annotation to @SpringBootTest and also tried to used @MockBean instead of @SpyBean but without any success. Actually I do not understand why my bean mailJobFinderTask is not created

Upvotes: 4

Views: 4455

Answers (2)

Murat Yıldız
Murat Yıldız

Reputation: 12032

As mentioned in the error message:

Examples of correct verifications:
verify(mock).someMethod(); verify(mock, times(10)).someMethod(); verify(mock, atLeastOnce()).someMethod(); not: verify(mock.someMethod());

You should update the following line:

.untilAsserted(() -> verify(mailJobFinderTask, atLeast(3)).findEmailJobs());

as shown below:

.untilAsserted(() -> verify(mailJobFinderTask, atLeast(3)).findEmailJobs();

Upvotes: 0

kosmasd
kosmasd

Reputation: 334

Your code seems to work fine on my system, but I had to do a few changes.

I would recommend these as starting points to your troubleshooting. Also, you haven't mentioned if you can successfully replicate the linked tutorial, which also runs fine on my system. If you haven't, I would recommend trying the tutorial first, confirming it works, and then adding your own code.

If the below does not help you, then it could be that the issue is not in the part of the code you posted. In that case, sharing the full code would help us better troubleshoot the problem. But for now, maybe pay particular attention to the import statements and the main changes listed below.

Changes from your code

  1. I changed the Duration.ofSeconds(3) method to Duration.FIVE_SECONDS. The reason for this is that the former is from java.time package, while await() expects a Duration class from the awaitility package. I just used FIVE_SECONDS for compatibility purposes.
  2. I had to remove the "extends SuppressedLogPoller" part, as I did not have access to this class. I would also recommend removing it and adding this back again to see if it is causing the issue.

Test class code

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;


import org.awaitility.Duration;

import static org.awaitility.Awaitility.await;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.verify;


@SpringJUnitConfig(ScheduledConfig.class)
public class MailJobFinderTaskIT {

    @SpyBean
    private MailJobFinderTask mailJobFinderTask;

    @Test
    public void whenWaitThreeSecond_ThenTaskCalledThreeTimes(){
        await()
                .atMost(Duration.FIVE_SECONDS)
                .untilAsserted(() -> verify(mailJobFinderTask, atLeast(7)).findEmailJobs());
    }
}

Domain class

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MailJobFinderTask {

    @Scheduled(fixedRate = 1200)
    public void findEmailJobs() {

    }

}

Upvotes: 3

Related Questions