我正在尝试创建一个 Junit 扩展,以便在所有测试之前创建一个 S3 模拟服务器,并在所有测试之后将其关闭。 S3 Mock 服务器应该使用我的 ApplicationProperties 类中的值,该类在术语中是一个 @ConfigurationProperties 类。
现在我正在使用这个简单的测试:
@ExtendWith({S3Extension.class})
@ActiveProfiles("test")
@SpringBootTest()
class S3OtherServiceItTest {
@Autowired private S3Service s3Service;
@MockBean SetupSchedulerJobs setupSchedulerJobs;
@MockBean DbStatus dbStatus;
@Test
public void test(AmazonS3Client client) throws IOException, FileException {
File file = new File("test.txt");
Files.write(file.toPath(), "contents".getBytes());
s3Service.uploadLocalFile(file.getPath(), "another/file/name");
client.listObjects("tkgpdf-bucket").getObjectSummaries().forEach(System.out::println);
}
}
到目前为止,这是我的 Junit 扩展:
@ExtendWith(SpringExtension.class)
public class S3Extension implements BeforeAllCallback, AfterAllCallback, ParameterResolver {
private S3Mock s3Mock;
private AmazonS3Client s3Client;
private ApplicationProperties applicationProperties;
@Override
public void beforeAll(ExtensionContext context) {
applicationProperties = SpringExtension.getApplicationContext(context).getBean(ApplicationProperties.class);
s3Mock = new S3Mock.Builder().withPort(9000).withFileBackend("build/s3").build();
s3Mock.start();
s3Client = getClient();
s3Client.createBucket(applicationProperties.getS3().getBucket());
}
@Override
public void afterAll(ExtensionContext context) {
if (s3Mock != null) {
s3Mock.shutdown();
}
}
@Override
public boolean supportsParameter(
ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
return parameterContext.getParameter().getType() == AmazonS3Client.class;
}
@Override
public Object resolveParameter(
ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
return s3Client;
}
public AmazonS3Client getClient() {
AwsClientBuilder.EndpointConfiguration endpoint =
new AwsClientBuilder.EndpointConfiguration(applicationProperties.getS3().getEndpoint(), "us-west-2");
return (AmazonS3Client)
AmazonS3ClientBuilder.standard()
.withPathStyleAccessEnabled(true)
.withEndpointConfiguration(endpoint)
.withCredentials(new AWSStaticCredentialsProvider(new AnonymousAWSCredentials()))
.build();
}
}
使用此配置,测试将失败并出现类似以下错误: 无法解析 bean,因为有 2 个 ApplicationProperties 类型的 Bean
那么,为什么要实例化两个 ApplicationProperties Bean 以及如何避免这种情况?我怀疑 @SpringBootTest 注释和 SpringExtension 都试图创建导致此错误的上下文?
这是因为您正在使用:
@ExtendWith({SpringExtension.class})
和@SpringBootTest()
。
您可以删除
@ExtendWith(SpringExtension.class)
。