I'm writing integration tests for an application that gets certain objects from Kafka, validates them, performs various conversions and either saves converted objects to another database or sends a response with errors back to Kafka.
The production database has several named queries that are mapped onto relating methods in the corresponding JpaRepository
, like so:
public interface PositionRepository extends JpaRepository<Position, Long> {
@Procedure(name = "generatePositionCode")
void generatePositionCode(@Param("clientCode") Integer clientCode);
//remainder omitted
I'm using the Mockito framework and the H2 in-memory database for integration testing. As the test database does not contain such named queries, I want to stub the corresponding methods in the repository and do nothing when they are called (which is ok for testing purposes), but continue calling other non-stubbed methods of the repository.
I've always thought that this is when you should use a spy in Mockito. However, when I define a spy like so:
@Spy
private PositionRespository positionRepository;
public void setUp() {
doNothing().when(positionRepository).generatePositionCode(anyInt());
}
my integration tests fail with an exception that boils down to:
Caused by: org.h2.jdbc.JdbcSQLException: Database "FT" not found; SQL statement: call FT.Ftposgn.generatePositionCode(?) [90013-197]
If on the other hand, I define a mock with delegation in a configuration class like so:
@Primary
@Bean
public PositionRepository mockPositionRepository(PositionRepository positionRepository) {
return Mockito.mock(PositionRepository.class,
AdditionalAnswers.delegatesTo(positionRepository));
}
and autowire the repository in the test class:
@Autowired
private PositionRepository positionRepository;
public void setUp() {
doNothing().when(positionRepository).generatePositionCode(anyInt());
}
all tests are green.
I've been trying to wrap my head around why these two methods produce different results but couldn't. Can anyone please shed some light?
Thanks.