我正在使用 Spring Boot (3.3.0) 和 Cucumber (7.18.0) 进行测试。我有一个想要模拟的存储库,并且我已经包含了 Spring 和 Cucumber 的必要(我认为)配置,但我得到了 “java.lang.NullPointerException:无法调用“com.example.sampleproject.repository.ArtistRepository.findById(Object)”,因为“this.artistRepository”为空”。
这是我的步骤定义课程:
@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));
}
然后我有 CucumberSpring 配置:
@CucumberContextConfiguration
@SpringBootTest(classes = SampleProjectApplication.class)
public class CucumberSpringConfiguration {
public CucumberSpringConfiguration() {
System.out.println("CucumberSpringConfiguration initialized");
}
}
测试运行者:
@Suite
@SelectClasspathResource("features")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example.sampleproject.steps, com.example.sampleproject.config")
public class TestRunner {
}
当我在 FindArtistByIdStepDefs 类上添加 @CucumberContextConfiguration 并删除其他类时,它可以工作。但我希望这个配置更加集中,因为我还有另一个步骤定义类并计划有更多。
使用集中配置时,什么可能导致 @MockBean 导致 NullPointerException?如何确保 MockBean 正确注入,同时保持集中配置?
您的步骤定义类应该如下所示。
public class FindArtistByIdStepDefs {
private final ArtistRepository artistRepository;
private final DataLoaderService dataLoaderService;
private List<ArtistEntity> mockedArtists = new ArrayList<>();
private List<AlbumEntity> mockedAlbums = new ArrayList<>();
public FindArtistByIdStepDefs(
DataLoaderService dataLoaderService,
ArtistRepository artistRepository
) {
this.dataLoaderService = dataLoaderService;
this.artistRepository = artistRepository;
}
...
你的上下文配置应该是这样的:
@CucumberContextConfiguration
@SpringBootTest(classes = SampleProjectApplication.class)
public class CucumberSpringConfiguration {
@MockBean
private ArtistRepository artistRepository;
}
通过将
ArtistRepository
声明为 MockBean
,模拟将被注入到 FindArtistByIdStepDefs
中。然后您可以像平常一样使用mockito。
此外,
CucumberSpringConfiguration
和 FindArtistByIdStepDefs
都应位于胶水路径上。如果它们在同一个包中,则可能是。