我有一个应用程序,其单元测试工作正常。我正在尝试移动应用程序使用依赖注入,而不是使用@AutoWired
注解。
在我进行更改之后,一些单元测试随机失败(没有对测试进行任何更改,只是更改了应用程序的依赖注入部分)。我假设在注入依赖时系统无法正确创建AmazonS3客户端。
请参见下面的屏幕截图,我正在尝试创建一个s3ClientAlphaBeta示例,但应用程序正在创建一个s3ClientGammaProd示例。
我还能错过什么呢?
缩写代码:
S3附件. java:
@Component
public class S3Accessor {
private AmazonS3 s3ClientAlphaBeta;
private AmazonS3 s3ClientGammaProd;
@Inject
public S3Accessor(@Qualifier("s3ClientAlphaBeta") AmazonS3 s3ClientAlphaBeta,
@Qualifier("s3ClientGammaProd") AmazonS3 s3ClientGammaProd) {
this.s3ClientAlphaBeta = s3ClientAlphaBeta;
this.s3ClientGammaProd = s3ClientGammaProd;
}
public String getHtmlContent(final String deviceType, final String s3Key, final String region) {
final String filePath = generateFilePath(deviceType.toLowerCase(Locale.ROOT), s3Key);
AmazonS3 amazonS3 = s3ClientAlphaBeta;
final String regionSpecificLegoBucket = S3BUCKET_NAME_BETA;
final AmazonS3 regionSpecificAmazonS3 = amazonS3;
return this.getHtmlContentFromS3(regionSpecificLegoBucket, filePath, regionSpecificAmazonS3);
}
private String getHtmlContentFromS3(final String bucketName, final String filePath, final AmazonS3 amazonS3) {
String s3HtmlContent = amazonS3.getObjectAsString(bucketName, filePath);
return s3HtmlContent;
}
S3附件测试. java:
public class S3AccessorTest {
@InjectMocks
private S3Accessor s3Accessor;
@Spy
@Qualifier("s3ClientAlphaBeta")
private AmazonS3 s3ClientAlphaBeta;
@Spy
@Qualifier("s3ClientGammaProd")
private AmazonS3 s3ClientGammaProd;
private static final String TEST_VALID_STRING_DESKTOP = "<html><body>Some Content For DESKTOP</body></html>";
private static final String TEST_VALID_WRAPPED_STRING_DESKTOP =
PAINTERS_LEGO_OPENING_DIV + TEST_VALID_STRING_DESKTOP + PAINTERS_LEGO_CLOSING_DIV;
private static final String TEST_VALID_S3_KEY = "/test/.1/main";
private static final String SLASH = "/";
static {
AppConfig.destroy();
AppConfig.initialize("TestApp",
"TestGroup",
new String[] { "--root=configuration/", "--domain=test", "--realm=Ramu" });
}
@BeforeEach
public void setup() {
MockitoAnnotations.openMocks(this);
s3Accessor.setup();
}
@Test
public void getHtmlContentForDesktop() {
// Arrange
when(s3ClientAlphaBeta.getObjectAsString(anyString(), eq(TEST_VALID_S3_KEY + SLASH + DESKTOP_VIEW)))
.thenReturn(TEST_VALID_STRING_DESKTOP);
// Act
final String outputString = s3Accessor.getHtmlContent(DESKTOP, TEST_VALID_S3_KEY, US_ALPHA_BETA_REGION);
// Assert
assertEquals(TEST_VALID_WRAPPED_STRING_DESKTOP, outputString);
}
自定义根配置.java:
@Configuration
@ComponentScan("com.service.controller")
@Import({SmokeTestBeanConfiguration.class })
public class CustomRootConfig {
private static final String NA_S3_SESSION_NAME = "S3Content";
private static final int S3_SESSION_REFRESH_TIME = 3600;
private static final String S3BUCKET_ARN_BETA = "arn:aws:iam::471963992020:role/ProdAccessForAccount";
private static final String S3BUCKET_ARN_PROD = "arn:aws:iam::568948772290:role/ProdAccessForAccount";
@Bean(name = "s3ClientAlphaBeta")
@Singleton
public AmazonS3 s3ClientAlphaBeta() {
return AmazonS3ClientBuilder.standard()
.withRegion(Regions.valueOf(US_ALPHA_BETA_REGION))
.withCredentials(new STSAssumeRoleSessionCredentialsProvider
.Builder(S3BUCKET_ARN_BETA, NA_S3_SESSION_NAME)
.withRoleSessionDurationSeconds(S3_SESSION_REFRESH_TIME).build())
.build();
}
@Bean(name = "s3ClientGammaProd")
@Singleton
public AmazonS3 s3ClientGammaProd() {
return AmazonS3ClientBuilder.standard()
.withRegion(Regions.valueOf(US_GAMMA_PROD_REGION))
.withCredentials(new STSAssumeRoleSessionCredentialsProvider
.Builder(S3BUCKET_ARN_PROD, NA_S3_SESSION_NAME)
.withRoleSessionDurationSeconds(S3_SESSION_REFRESH_TIME).build())
.build();
}
1条答案
按热度按时间deikduxw1#
我认为Mockito实际上并不能识别Spring中的
@Qualifier
注解,它以前工作的原因是Mockito进行了属性注入,因为没有其他方法可以做到这一点。修改之后,在构造函数就位的情况下,Mockito从属性注入切换到构造函数注入。(
AmazonS3
).显然,使用构造函数注入时,Mockito不能很好地按名称区分参数,可能的原因是参数的名称在编译后没有保留,因此Mockito无法匹配它们,而是使用它找到的第一个具有匹配类型(s3ClientAlphaBeta
或s3ClientGammaProd
)的mock(spy),并将其用于两个参数以构造S3Accessor
的示例。为了避免您的问题并获得更多对如何创建被测试对象的控制,我建议放弃使用
@InjectMocks
并直接在被测试类中使用构造函数,即:低于
MockitoAnnotations.openMocks(this)
的某个值。您可以找到有关
@InjectMocks
注解如何工作here的更多信息。