Почему метод конструктора вызывается перед установкой - PullRequest
0 голосов
/ 11 января 2019

Вот мой тестируемый класс:

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.

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()));
}

}

Вот тестовый класс:

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);
    }

Я хочу издеваться над шаблоном kafka. Но его реализация в конструкторе, который выполняется еще до выполнения @Before, где написана логика насмешки над методом.

Просто любопытно, почему конструктор выполняется первым, а также, как я могу издеваться над методом, если это так? Каковы могут быть способы насмешки над kafkaTemplate без использования Powermock и без изменения тестируемого класса, поскольку я не могу его изменить?

1 Ответ

0 голосов
/ 11 января 2019

Когда вы используете @SpringBootTest, дерево зависимостей Spring разрешается до того, как метод @Before сможет выполнить. Это включает в себя создание компонента KafkaProcessorApplication и его зависимостей. Вот почему конструктор работает до @Before.

То, что вам нужно, это @MockBean Spring для создания и внедрения фиктивного компонента в контексте приложения.

В этом вопросе подробно описывается, как вы можете использовать это: Разница между @Mock, @MockBean и Mockito.mock ()

обновление

Теперь я вижу. Проблема в том, что KafkaProcessorApplication обращается к макету в его конструкторе, прежде чем вы сможете его настроить.

Эту проблему можно решить с помощью отдельной тестовой конфигурации Spring, которая будет возвращать сконфигурированный фиктивный бин SenderConfig, как описано здесь: Тестирование пружинного бина с пост-конструкцией

...