我有这个课: SqssReadderApp :
@Autowired
private Source source;
@Autowired
private AWSProperties awsProperties;
@Autowired
private AuditRepository auditRepository;
private AmazonSQS sqs;
@Autowired
public SqssreaderApplication(AWSConfig awsConfig) {
this.sqs = awsConfig.generateSQS();
}
它正在从其构造函数中调用方法generateSQS()。 SQS是通过调用静态方法生成的。 这是包含该方法的相关类:
@Autowired
private AWSProperties awsProperties;
@Bean
AmazonSQS generateSQS() {
return AmazonSQSClientBuilder.standard()
.withRegion(awsProperties.getQueueRegion())
.build();
}
现在,在我的测试类中,我正在尝试通过注入mockAwsConfig来模拟generateSQS()方法调用。 我认为有两种方法可以将SockSqs实例注入SqssReaderApplication中。
方法1: 我将mockAwsConfig注入构造函数,并使用以下规则对其进行初始化:
when(mockAwsConfig.generateSQS()).thenReturn(mockSQS);
SqssReaderApplication app = new SqssReaderApplication(mockAwsConfig);
问题: 所有重新折叠(@Autowired)实体均保持为空。
方法2: 我@Autowired SqssReaderApplication,所有其他字段都被模拟,但是SqssReaderApplication中的sqs实例保持为空。
**TestClass**:
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@TestPropertySource(locations = "classpath:application-test.properties")
@SpringBootTest
@ContextConfiguration(classes = {SqssreaderApplication.class,
DefaultFrameworkSupport.class, AWSConfig.class, AuditRepository.class, FileProcessAuditLog.class})
public class SqssreaderApplicationTests {
@Autowired
private Source source;
@MockBean
AuditRepository auditRepository;
@Mock
private AmazonSQSClient amazonSQS;
@Mock
private AWSConfig awsConfig;
@InjectMocks
private SqssreaderApplication app;
@Mock
private AWSProperties awsProperties;
@Before
public void setup(){
MockitoAnnotations.initMocks(this);
when(awsConfig.generateSQS()).thenReturn(amazonSQS);
app = new SqssreaderApplication(awsConfig);
}
我也看到了其他答案,但是在这种情况下它们不起作用。 解决此问题的其他方法是什么?我应该如何在SqssReaderApp中注入模拟,最好不要使用PowerMock或修改源代码?
答案 0 :(得分:1)
您正在混合两种方式的依赖项注入(https://en.wikipedia.org/wiki/Dependency_injection#Three_types_of_dependency_injection)。您应该创建适当的构造函数,并且只有此委托方应该是@Autowired。 您的课程应类似于:
private Source source;
private AWSProperties awsProperties;
private AuditRepository auditRepository;
private AmazonSQS sqs;
@Autowired
public SqssreaderApplication(Source source, AWSProperties awsProperties, AuditRepository auditRepository, AWSConfig awsConfig) {
this.sqs = awsConfig.generateSQS();
然后在测试中,您可以修改#1方法并通过构造函数添加所有必需的模拟。 小麻烦:您正在AWSConfig和SqssreaderApplication类中使用AWSProperties。在SqssreaderApplication中检查您是否真的需要它。
答案 1 :(得分:0)
AmazonSQS
也是一个可以注入@Autowired
的spring bean。因此,您可以从更改
@Autowired
public SqssReadderApp(AWSConfig awsConfig) {
this.sqs = awsConfig.generateSQS();
}
到
@Autowired
public SqssReadderApp(AmazonSQS sqs) {
this.sqs = sqs;
}
现在,您可以将模拟的实例注入到构造函数中。
您还应该考虑解决字段注入和构造函数注入的这种混合问题。我建议使用构造函数注入,这会使测试更加容易。
public class SqssReadderApp {
@Autowired
public SqssReadderApp(Source source, AWSProperties awsProperties, AuditRepository auditRepository, AmazonSQS sqs) {
//
}
}