Бин не найден для определения [SpyDefinition ... при использовании @SpyBean - PullRequest
0 голосов
/ 01 октября 2019

У меня есть приложение, которое прослушивает сообщения Kafka, используя @KafkaListener внутри @Component. Теперь я хотел бы сделать интеграционный тест с контейнером тестирования Kafka (который раскручивает Kafka в фоновом режиме). В моем тесте я хочу убедиться, что метод слушателя был вызван и завершен, однако, когда я использую @SpyBean в своем тесте, я получаю:

No bean found for definition [SpyDefinition@7a939c9e name = '', typeToSpy = com.demo.kafka.MessageListener, reset = AFTER]

Я использую Котлинг, важные классы:

Класс для тестирования

@Component
class MessageListener(private val someRepository: SomeRepository){

    @KafkaListener
    fun listen(records: List<ConsumerRecord<String, String>>) {
         // do something with someRepository
    }
}

Базовый тестовый класс

@ExtendWith(SpringExtension::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class KafkaContainerTests {

    // some functionality to spin up kafka testcontainer

}

Тестовый класс

class MessageListenerTest @Autowired constructor(
        private val someRepository: SomeRepository
) : KafkaContainerTests() {


    @SpyBean
    private lateinit var messageListenerSpy: MessageListener

    private var messageListenerLatch = CountDownLatch(1)

    @BeforeAll
    fun setupLatch() {
        logger.debug("setting up latch")

        doAnswer {
            it.callRealMethod()
            messageListenerLatch.count
        }.whenever(messageListenerSpy).listen(any())
    }

    @Test
    fun testListener(){
        sendKafkaMessage(someValidKafkaMessage)

        // assert that the listen method is being called & finished
        assertTrue(messageListenerLatch.await(20, TimeUnit.SECONDS))
        // and assert someRepository is called
    }
}

Причина, по которой я запутался, заключается в том, что когда я добавляю MessageListener в конструктор @Autowired MessageListenerTest, он действительно успешно внедряется.

Почему тест не может найти компонент при использовании @SpyBean?

1 Ответ

1 голос
/ 01 октября 2019

У меня нормально работает с Java:

@SpringBootTest
class So58184716ApplicationTests {

    @SpyBean
    private Listener listener;

    @Test
    void test(@Autowired KafkaTemplate<String, String> template) throws InterruptedException {
        template.send("so58184716", "foo");
        CountDownLatch latch = new CountDownLatch(1);
        willAnswer(inv -> {
            inv.callRealMethod();
            latch.countDown();
            return null;
        }).given(this.listener).listen("foo");
        assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
        verify(this.listener).listen("foo");
    }

}

@SpringBootApplication
public class So58184716Application {

    public static void main(String[] args) {
        SpringApplication.run(So58184716Application.class, args);
    }


    @Bean
    public NewTopic topic() {
        return TopicBuilder.name("so58184716").partitions(1).replicas(1).build();
    }
}

@Component
class Listener {

    @KafkaListener(id = "so58184716", topics = "so58184716")
    public void listen(String in) {
        System.out.println(in);
    }

}

enter image description here

...