I am testing with Spring Boot (3.3.0) and Cucumber (7.18.0). I have a repository which I want to mock and I have included the necessary (I think) configuration for Spring and Cucumber but I get
“java.lang.NullPointerException: Cannot invoke “com.example.sampleproject.repository.ArtistRepository.findById(Object)” because “this.artistRepository” is null”.
Here is my step def class:
@ContextConfiguration(classes = {SampleProjectApplication.class, CucumberSpringConfiguration.class})
public class FindArtistByIdStepDefs {
private ArtistRepository artistRepository;
private DataLoaderService dataLoaderService;
private List<ArtistEntity> mockedArtists = new ArrayList<>();
private List<AlbumEntity> mockedAlbums = new ArrayList<>();
public FindArtistByIdStepDefs(DataLoaderService dataLoaderService) {
this.dataLoaderService = dataLoaderService;
@Given("artists exist in the DB")
public void theFollowingArtistsExistInTheDB(DataTable dataTable) {
List<Map<String, String>> map = dataTable.asMaps(String.class, String.class);
for (Map<String, String> row : map) {
ArtistEntity artist = new ArtistEntity();
String name = row.get("name");
String description = row.get("description");
long id = Long.parseLong(row.get("id"));
artist.setDescription(description);
mockedArtists.add(artist);
Mockito.when(artistRepository.findById(artist.getId())).thenReturn(Optional.of(artist));
<code>@SpringBootTest
@ContextConfiguration(classes = {SampleProjectApplication.class, CucumberSpringConfiguration.class})
public class FindArtistByIdStepDefs {
@MockBean
private ArtistRepository artistRepository;
private DataLoaderService dataLoaderService;
private List<ArtistEntity> mockedArtists = new ArrayList<>();
private List<AlbumEntity> mockedAlbums = new ArrayList<>();
public FindArtistByIdStepDefs(DataLoaderService dataLoaderService) {
this.dataLoaderService = dataLoaderService;
}
@Given("artists exist in the DB")
public void theFollowingArtistsExistInTheDB(DataTable dataTable) {
List<Map<String, String>> map = dataTable.asMaps(String.class, String.class);
for (Map<String, String> row : map) {
ArtistEntity artist = new ArtistEntity();
String name = row.get("name");
String description = row.get("description");
long id = Long.parseLong(row.get("id"));
artist.setArtist(name);
artist.setDescription(description);
artist.setId(id);
mockedArtists.add(artist);
Mockito.when(artistRepository.findById(artist.getId())).thenReturn(Optional.of(artist));
}
</code>
@SpringBootTest
@ContextConfiguration(classes = {SampleProjectApplication.class, CucumberSpringConfiguration.class})
public class FindArtistByIdStepDefs {
@MockBean
private ArtistRepository artistRepository;
private DataLoaderService dataLoaderService;
private List<ArtistEntity> mockedArtists = new ArrayList<>();
private List<AlbumEntity> mockedAlbums = new ArrayList<>();
public FindArtistByIdStepDefs(DataLoaderService dataLoaderService) {
this.dataLoaderService = dataLoaderService;
}
@Given("artists exist in the DB")
public void theFollowingArtistsExistInTheDB(DataTable dataTable) {
List<Map<String, String>> map = dataTable.asMaps(String.class, String.class);
for (Map<String, String> row : map) {
ArtistEntity artist = new ArtistEntity();
String name = row.get("name");
String description = row.get("description");
long id = Long.parseLong(row.get("id"));
artist.setArtist(name);
artist.setDescription(description);
artist.setId(id);
mockedArtists.add(artist);
Mockito.when(artistRepository.findById(artist.getId())).thenReturn(Optional.of(artist));
}
Then I have CucumberSpring config:
<code>@CucumberContextConfiguration
@SpringBootTest(classes = SampleProjectApplication.class)
public class CucumberSpringConfiguration {
public CucumberSpringConfiguration() {
System.out.println("CucumberSpringConfiguration initialized");
<code>@CucumberContextConfiguration
@SpringBootTest(classes = SampleProjectApplication.class)
public class CucumberSpringConfiguration {
public CucumberSpringConfiguration() {
System.out.println("CucumberSpringConfiguration initialized");
}
}
</code>
@CucumberContextConfiguration
@SpringBootTest(classes = SampleProjectApplication.class)
public class CucumberSpringConfiguration {
public CucumberSpringConfiguration() {
System.out.println("CucumberSpringConfiguration initialized");
}
}
Test Runner:
@SelectClasspathResource("features")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example.sampleproject.steps, com.example.sampleproject.config")
public class TestRunner {
<code>@Suite
@SelectClasspathResource("features")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example.sampleproject.steps, com.example.sampleproject.config")
public class TestRunner {
}
</code>
@Suite
@SelectClasspathResource("features")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example.sampleproject.steps, com.example.sampleproject.config")
public class TestRunner {
}
When I add @CucumberContextConfiguration on the FindArtistByIdStepDefs class and remove the other it works. But I want this configuration to be more centralized since I have another step def class and plan to have more.
What might be causing @MockBean to result in a NullPointerException when using a centralized configuration? How can I ensure that the MockBean is properly injected while keeping a centralized configuration?