Why doesn't the following when
stub of a service method work? I see that when I run the test, the real ar11applicationService's processEligibleRecords
is called, not the stub that I created. I am testing an Application whose run
will call the Service method. The anyString/anyInt
param options are used to create the stub.
@SpringBootTest
@RunWith(MockitoJUnitRunner.class)
@ExtendWith(MockitoExtension.class)
class Ar11ApplicationTest {
@Mock
Ar11ApplicationService ar11ApplicationService;
@Mock
EmailService emailService;
@InjectMocks // inject into the object we're testing
Ar11Application ar11Application;
@BeforeEach
void setUp() throws Exception {
// This is the stub that should get called - 9 params, next-to-last is Int, all others String
Mockito.when(ar11ApplicationService.processEligibleRecords(Mockito.anyString(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyInt(), Mockito.anyString()))
.thenReturn(new Ar11ResultBean());
}
@Test
void main() throws Exception {
org.junit.jupiter.api.Assertions.assertDoesNotThrow(
()->
{
ar11Application.run(new String[] {});
}
);
}
}
Service Implementation class's method (Ar11ApplicationServiceImpl implements Ar11ApplicationService
):
@Component
public class Ar11ApplicationServiceImpl implements Ar11ApplicationService {
@Override
@Transactional(readOnly = false, rollbackFor = Exception.class)
public Ar11ResultBean processEligibleRecords(String eligibleFilename, String newFilename,
String sourceDir, String sftpUserName,
String sftpPrivateKeyPath, String sftpPrivateKeyPassphrase,
String sftpHost, Integer sftpPort, String remoteDir)
throws Exception {
The application class that I'm testing is
@SpringBootApplication
public class Ar11Application implements CommandLineRunner {
// General properties
@Value("${AR11_ELIGIBLE_FILENAME}")
private String eligibleFilename;
@Value("${AR11_NEW_FILENAME_PREFIX}")
private String newFilenamePrefix;
// SFTP properties
@Value("${AR11_SFTP_USERNAME}")
private String sftpUserName;
@Value("${AR11_SFTP_KEY_PATH}")
private String sftpPrivateKeyPath;
@Value("${AR11_SFTP_PASSPHRASE}")
private String sftpPrivateKeyPassphrase;
@Value("${AR11_SFTP_HOST}")
private String sftpHost;
@Value("${AR11_SFTP_PORT}")
private Integer sftpPort;
@Value("${AR11_SFTP_SOURCE_DIR}")
private String sourceDir;
@Value("${AR11_SFTP_TARGET_DIR}")
private String remoteDir;
@Autowired
Ar11ApplicationService ar11ApplicationService;
@Override
public void run(String... args) throws Exception {
try {
Ar11ResultBean ar11ResultBean = ar11ApplicationService.processEligibleRecords(eligibleFilename, newFilename, sourceDir,
sftpUserName, sftpPrivateKeyPath, sftpPrivateKeyPassphrase, sftpHost, sftpPort, remoteDir);
The answer, per @tgdavies, was to remove @SpringBootTest
at the top. It should be this:
@RunWith(MockitoJUnitRunner.class) // No @SpringBootTest!
@ExtendWith(MockitoExtension.class)
class Ar11ApplicationTest {
@Mock
Ar11ApplicationService ar11ApplicationService;
@Mock
EmailService emailService;
@InjectMocks
Ar11Application ar11Application;
@BeforeEach
void setUp() throws Exception {
Mockito.when(ar11ApplicationService.processEligibleRecords(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyString()))
.thenReturn(new Ar11ResultBean(500));
I verified in the debugger that as soon as @SpringBootTest
is added, it immediately goes to the real Service class's code without even doing setUp
in this unit test. Thanks for the help.