是否有其他方法可以在构造函数中模拟此方法调用



我有这个类:SqssAdderApp

@Autowired
private Source source;
@Autowired
private AWSProperties awsProperties;
@Autowired
private AuditRepository auditRepository;
private AmazonSQS sqs;
@Autowired
public SqssreaderApplication(AWSConfig awsConfig) {
this.sqs = awsConfig.generateSQS();
}

它正在从构造函数中调用方法generateQS()。SQS是通过调用一个静态方法生成的。以下是包含方法的相关类:

@Autowired
private AWSProperties awsProperties;
@Bean
AmazonSQS generateSQS() {
return AmazonSQSClientBuilder.standard()
.withRegion(awsProperties.getQueueRegion())
.build();
}

现在,在我的测试类中,我试图通过注入mockAwsConfig来模拟这个generateQS()方法调用。我认为有两种方法可以在SqsReaderApplication中注入mockSqs实例。

方法1:我将mockAwsConfig注入构造函数,并使用以下规则对其进行初始化:

when(mockAwsConfig.generateSQS()).thenReturn(mockSQS);
SqssReaderApplication app = new SqssReaderApplication(mockAwsConfig);

问题:所有的remaning(@Autowired)实体保持为空。

方法2:我@Autowired了SqssReaderApplication,所有其他字段都被模拟了,但SqssRead应用程序中的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中注入mock,最好不要使用PowerMock或修改源代码?

您混合了两种依赖注入方式(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方法,并通过构造函数添加所有必需的mock。小提示:您在AWSConfig和SqssreaderApplication类中都使用AWSProperty。在SqssreaderApplication中查看您是否真的需要它。

AmazonSQS也是一个可以注入@Autowired的springbean。因此,您可以从更改构造函数

@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) {
//
}
}

另请参阅为什么现场注射是邪恶的。

最新更新