首页 > 解决方案 > 为什么在设置之前调用构造函数方法

问题描述

这是我正在测试的课程:

KafkaProcessorApplication

@EnableBinding(Processor.class)
@EnableConfigurationProperties(KafkaProperties.class)
public class KafkaProcessorApplication {

    @Autowired
    private Processor processor;

    @Autowired
    private KafkaProperties kafkaProperties;

    private KafkaTemplate<String, String> kafkaTemplate;

    @Autowired
    KafkaProcessorApplication(SenderConfig senderConfig) {
        this.kafkaTemplate = senderConfig.kafkaTemplate();
    }

在这里,SenderConfig 只是一个简单的配置类,其方法 kafkaTemplate() 创建了一个新的 KafkaTemplate 实例。

发件人配置

@Configuration
public class SenderConfig {
@Autowired
KafkaProperties kafkaProperties;

public ProducerFactory<String, String> producerFactory() {
    return new DefaultKafkaProducerFactory<>(new HashMap());
}

public KafkaTemplate<String, String> kafkaTemplate() {
    return new KafkaTemplate<>(ProducerFactory()));
}

}

这是测试类:

KafkaTestClass

@SpringBootTest
@ActiveProfiles("test")
@ContextConfiguration(classes = {SenderConfig.class, KafkaProcessorApplication.class})
@TestPropertySource(locations = "classpath:test-resources.properties")
@RunWith(SpringRunner.class)
public class KafkaProcessorApplicationTest {

    @Autowired
    private Processor processor;
    @Mock
    private SenderConfig senderConfig;

    @Mock
    private KafkaProperties kafkaProperties = new KafkaProperties();
    @Mock private KafkaTemplate mockKafka;

    @Autowired
    @InjectMocks
    private KafkaProcessorApplication app;

    @Before
    public void setup() throws Exception {
        MockitoAnnotations.initMocks(this);
        doReturn("ServerConfig").when(kafkaProperties).getServersConfig();
        when(senderConfig.kafkaTemplate()).thenReturn(kafkaTemplate);
    }

我想模拟 kafkaTemplate。但是,它的实例化在构造函数中,该构造函数甚至在执行 @Before 之前就已执行,其中编写了模拟方法的逻辑。

只是好奇为什么首先执行构造函数,如果是这种情况,我该如何模拟该方法?模拟 kafkaTemplate 的方法是什么,不使用 Powermock 并且不修改被测类,因为我无法更改它?

标签: javaunit-testingmockitospring-cloud-dataflow

解决方案


当你使用@SpringBootTest时,Spring 依赖树在@Before方法有机会执行之前就被解析了。这包括构建KafkaProcessorApplicationbean 及其依赖项。这就是构造函数在之前运行的原因@Before

您想要的是 Spring@MockBean在应用程序上下文中创建和注入模拟 bean。

这个问题对如何使用它有很好的描述:@Mock、@MockBean 和 Mockito.mock() 之间的区别

更新

现在我明白了。问题是KafkaProcessorApplication在你可以配置它之前访问它的构造函数中的模拟。

这可以通过单独的测试 Spring 配置来解决,该配置将返回配置的 SenderConfig 模拟 bean,如下所述:使用 post 构造测试 spring bean


推荐阅读