Java 为什么在安装之前调用构造函数方法

Java 为什么在安装之前调用构造函数方法,java,unit-testing,mockito,spring-cloud-dataflow,Java,Unit Testing,Mockito,Spring Cloud Dataflow,这是我正在测试的班级: 卡夫卡处理器应用程序 @EnableBinding(Processor.class) @EnableConfigurationProperties(KafkaProperties.class) public class KafkaProcessorApplication { @Autowired private Processor processor; @Autowired private KafkaProperties kafkaPr

这是我正在测试的班级:

卡夫卡处理器应用程序

@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();
    }
我想模仿卡夫卡模板。但是,它的实例化是在构造函数中执行的,甚至在@before被执行之前就已经执行了,在这里模拟方法的逻辑被编写

我只是好奇为什么先执行构造函数,如果是这样的话,我怎么能模拟这个方法呢?
模拟kafkaTemplate的方法是什么,而不使用Powermock,也不修改测试中的类,因为我无法更改它?

当您使用
@SpringBootTest
时,在
@before
方法有机会执行之前,Spring依赖关系树会被解析。这包括构造
kafkapprocessorapplication
bean及其依赖项。这就是构造函数在之前运行的原因

您想要的是Spring的
@MockBean
在应用程序上下文中创建并注入一个MockBean

这个问题对你如何使用它有一个很好的总结:

更新 现在我明白了。问题在于
kafkapprocessorApplication
在您可以配置它之前访问其构造函数中的mock


这可以通过一个单独的test Spring配置来解决,该配置将返回一个配置好的SenderConfig mock bean,如下所述:

好的,我使用了许多选项来模拟被调用方法的行为,但它始终保持null,或者在使用MockBean的情况下,创建新实例,因此,我如何定义它的行为?你到底想模仿哪个bean?使用您当前的测试代码很难判断。该mock必须应用@MockBean。我链接到的问题的第一个答案中的示例看起来很好,我想模拟在构造函数调用中创建的KafkaTemplate。我想要一个清晰的方法,不改变源代码,你确定吗?看起来SenderConfig就是您要模拟的bean。我没有看到任何KafkCatemplate bean。我已经可以模拟SenderConfig了,只是,它正在实例化KafkCatemplate,然后才能模拟这个模拟SenderConfig的方法调用。
@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()));
}
@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);
    }