Rajkishan Swami
Rajkishan Swami

Reputation: 3759

Using @SpyBean with @Qualifier Spring Boot Test

I have 2 DataSources in my app.

So, to get the required JdbcTemplate, i use @Qualifier. But, when i do like below, the test runs... but stays waiting indefinitely, if there is any use of JdbcTemplate in the "Method Under Test".

@Service
@Transactional
public class SampleDatabaseService {

    @Autowired
    @Qualifier("firstDbJdbcTemplate")
    private JdbcTemplate firstDbJdbcTemplate;

    @Autowired
    @Qualifier("secondDbJdbcTemplate")
    private JdbcTemplate secondDbJdbcTemplate;

    @Cacheable("status")
    public Map<String, Device> readAllValidDeviceStatus() {
        Map<String, Device> allDeviceStatuses = new HashMap<>();
        //Stops at below line indefinitely if "SpyBean" is used
        List<StatusDetail> statusDetails = firstDbJdbcTemplate
               .query(SqlQueries.READ_DEVICE_STATUS, BeanPropertyRowMapper.newInstance(StatusDetail.class)); 

        statusDetails
               .stream()
               .filter(deviceStatus -> deviceStatus.getName() != "Some Invalid Name")
               .forEach(deviceStatus -> allDeviceStatuses
                  .put(deviceStatus.getName(), buildDevice(deviceStatus)));
        return allDeviceStatuses;
    }

/** More Stuff **/

}

and the Test :

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
@Rollback
@ActiveProfiles("test")
public class SampleDatabaseServiceTest {

    @SpyBean
    @Qualifier("firstDbJdbcTemplate")
    private JdbcTemplate firstDbJdbcTemplate;

    @Autowired
    private SampleDatabaseService serviceUnderTest;

    @Before
    public void populateTables() {
        //Insert some Dummy Records in "InMemory HSQL DB" using firstDbJdbcTemplate
    }


    @Test
    public void testReadAllValidDeviceStatus() {
        // When
        Map<String, Device> allDeviceStatuses = serviceUnderTest.readAllValidDeviceStatus();

        // Then
        assertThat(allDeviceStatuses).isNotNull().isNotEmpty();
        // More checks
    }
    /* More Tests */
}

But, when i replace the @SpyBean with @Autowired in Test, it works fine.

Why is it so? Any help is greatly appreciated. :)

Upvotes: 4

Views: 3135

Answers (2)

Sajad
Sajad

Reputation: 2363

You can simply use name attribute of SpyBean annotation

@SpyBean(name = "firstDbJdbcTemplate")
private JdbcTemplate firstDbJdbcTemplate;

Upvotes: 1

Kailas Andhale
Kailas Andhale

Reputation: 53

Use it in below format

  @MockBean(name = "firstDbJdbcTemplate") 
  private JdbcTemplate firstDbJdbcTemplate;

Upvotes: 1

Related Questions