Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 为什么我的卡夫卡侦听器在我的单元测试中不工作_Unit Testing_Spring Kafka - Fatal编程技术网

Unit testing 为什么我的卡夫卡侦听器在我的单元测试中不工作

Unit testing 为什么我的卡夫卡侦听器在我的单元测试中不工作,unit-testing,spring-kafka,Unit Testing,Spring Kafka,问题 我试图对发送整数的卡夫卡制作者进行单元测试。当运行单元测试时,我可以看到输出,表明我的生产者和消费者在控制台中工作正常。也就是说,生产者发送的值为零,消费者收到的值为零,并将该整数与运行的总和相加 sending data = 0 received content = 0 sending total = 0 但是,当测试消费者记录返回空条目时,单元测试最终失败。我猜听众根本不工作 java.lang.AssertionError: Expected: a ConsumerRecord

问题

我试图对发送整数的卡夫卡制作者进行单元测试。当运行单元测试时,我可以看到输出,表明我的生产者和消费者在控制台中工作正常。也就是说,生产者发送的值为零,消费者收到的值为零,并将该整数与运行的总和相加

sending data = 0
received content = 0
sending total = 0
但是,当测试消费者记录返回空条目时,单元测试最终失败。我猜听众根本不工作

java.lang.AssertionError: 
Expected: a ConsumerRecord with value 0
     but: is null
问题

我定义容器/messageListener的方式是否有错误?还是我的单元测试有更根本的问题

此url包含我的producer/config和consumer/config的代码。在那里查看它可能比在这里创建庞大的代码部分更容易

单元测试

package com.calculator;

/**
 * Created by ian on 2/9/18.
 */
import com.calculator.kafka.services.KafkaProducer;
import com.calculator.kafka.services.KafkaConsumer;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import org.springframework.kafka.listener.KafkaMessageListenerContainer;
import org.springframework.kafka.listener.MessageListener;
import org.springframework.kafka.listener.config.ContainerProperties;
import org.springframework.kafka.test.rule.KafkaEmbedded;
import org.springframework.kafka.test.utils.ContainerTestUtils;
import org.springframework.kafka.test.utils.KafkaTestUtils;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertThat;
import static org.springframework.kafka.test.assertj.KafkaConditions.key;
import static org.springframework.kafka.test.hamcrest.KafkaMatchers.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@DirtiesContext
public class KafkaTest {

    // in case I need to send some integers
    private Integer i1 = 0;
    private Integer i2 = 3;

    private static final String SENDER_TOPIC = "input";

    private List<Integer> l1;

    @Autowired
    private KafkaProducer producer;

    @Autowired
    private KafkaConsumer consumer;

    private KafkaMessageListenerContainer<String, Integer> container;

    private BlockingQueue<ConsumerRecord<String, Integer>> records;

    private static final Logger LOGGER = LoggerFactory.getLogger(KafkaTest.class);


    @ClassRule
    public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, SENDER_TOPIC);



    @Before
    public void testTemplate() throws Exception {

        // set up the Kafka consumer properties
        Map<String, Object> consumerProperties = KafkaTestUtils.consumerProps("test-group", "false", embeddedKafka);

        // create a Kafka consumer factory
        DefaultKafkaConsumerFactory<String, Integer> consumerFactory = new DefaultKafkaConsumerFactory<>(consumerProperties);

        // set the topic that needs to be consumed
        ContainerProperties containerProperties = new ContainerProperties(SENDER_TOPIC);

        // create a Kafka MessageListenerContainer
        container = new KafkaMessageListenerContainer<>(consumerFactory, containerProperties);

        // create a thread safe queue to store the received message
        records = new LinkedBlockingQueue<>();

        // setup a Kafka message listener
        container.setupMessageListener(new MessageListener<String, Integer>() {
            @Override
            public void onMessage(ConsumerRecord<String, Integer> record) {
                LOGGER.debug("test-listener received message='{}'", record.toString());
                records.add(record);
            }
        });

        // start the container and underlying message listener
        container.start();

        // wait until the container has the required number of assigned partitions
        ContainerTestUtils.waitForAssignment(container, embeddedKafka.getPartitionsPerTopic());


    }

    @After
    public void tearDown() {
        // stop the container
        container.stop();
    }

    @Test
    public void testSend() throws InterruptedException {
        // send the message
        producer.send(i1);

        // check that the message was received
        ConsumerRecord<String, Integer> received = records.poll(10, TimeUnit.SECONDS);
        // Hamcrest Matchers to check the value
        assertThat(received, hasValue(i1));

        // AssertJ Condition to check the key
        assertThat(received, hasKey(null));
    }
}
package.com.calculator;
/**
*由ian于2018年2月9日创建。
*/
导入com.calculator.kafka.services.KafkaProducer;
导入com.calculator.kafka.services.KafkaConsumer;
导入org.apache.kafka.clients.consumer.ConsumerRecord;
导入org.junit.After;
导入org.junit.Before;
导入org.junit.ClassRule;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.boot.test.context.SpringBootTest;
导入org.springframework.kafka.core.DefaultKafkaConsumerFactory;
导入org.springframework.kafka.core.DefaultKafkaProducerFactory;
导入org.springframework.kafka.core.KafkaTemplate;
导入org.springframework.kafka.core.ProducerFactory;
导入org.springframework.kafka.listener.KafkaMessageListenerContainer;
导入org.springframework.kafka.listener.MessageListener;
导入org.springframework.kafka.listener.config.ContainerProperties;
导入org.springframework.kafka.test.rule.kafkamebedded;
导入org.springframework.kafka.test.utils.ContainerTestUtils;
导入org.springframework.kafka.test.utils.KafkaTestUtils;
导入org.springframework.test.annotation.DirtiesContext;
导入org.springframework.test.context.junit4.SpringRunner;
导入java.util.List;
导入java.util.Map;
导入java.util.concurrent.BlockingQueue;
导入java.util.concurrent.LinkedBlockingQueue;
导入java.util.concurrent.TimeUnit;
导入静态org.junit.Assert.assertThat;
导入静态org.springframework.kafka.test.assertj.KafkaConditions.key;
导入静态org.springframework.kafka.test.hamcrest.KafkaMatchers.*;
@RunWith(SpringRunner.class)
@春靴测试
@肮脏的环境
公共级卡夫卡捷斯特{
//以防我需要发送一些整数
私有整数i1=0;
私有整数i2=3;
私有静态最终字符串发送者\u TOPIC=“input”;
私人名单l1;
@自动连线
私人卡夫卡制作人;
@自动连线
私人卡夫卡消费品;
卡夫卡专用集装箱;
私有阻塞队列记录;
私有静态最终记录器Logger=LoggerFactory.getLogger(KafkaTest.class);
@阶级规则
public static kafkamebedded embedded kafka=新的kafkamebedded(1,true,发送方\主题);
@以前
public void testTemplate()引发异常{
//设置卡夫卡消费者属性
Map consumerProperties=KafkaTestUtils.consumerProps(“测试组”,“假”,嵌入kafka);
//创建卡夫卡消费品工厂
DefaultKafkaConsumerFactory consumerFactory=新的DefaultKafkaConsumerFactory(consumerProperties);
//设置需要使用的主题
ContainerProperties ContainerProperties=新的ContainerProperty(发送者主题);
//创建Kafka MessageListenerContainer
容器=新的KafkaMessageListenerContainer(consumerFactory、containerProperties);
//创建线程安全队列以存储收到的消息
记录=新建LinkedBlockingQueue();
//设置卡夫卡消息侦听器
container.setupMessageListener(新MessageListener(){
@凌驾
信息公开无效(消费者记录记录){
debug(“测试侦听器收到的消息='{}',record.toString());
记录。添加(记录);
}
});
//启动容器和底层消息侦听器
container.start();
//等待容器具有所需数量的分配分区
ContainerTestUtils.waitForAssignment(容器,embeddedKafka.getPartitionsPerTopic());
}
@之后
公共无效拆卸(){
//停止容器
container.stop();
}
@试验
public void testSend()引发InterruptedException{
//发送消息
producer.send(i1);
//检查消息是否已收到
接收到的ConsumerRecord=记录。轮询(10,时间单位。秒);
//Hamcrest匹配器检查值
资产(已收到,具有价值(i1));
//AssertJ条件检查钥匙
资产(已接收,hasKey(null));
}
}

您需要使用正确的键/值序列化器/反序列化器。KTU分别为Integer/String设置,您需要String/Integer

您的测试用例的此修改版本有效

@RunWith(SpringRunner.class)
@SpringBootTest
@DirtiesContext
public class KafkaTest {

    // in case I need to send some integers
    private final Integer i1 = 0;

    private final Integer i2 = 3;

    private static final String SENDER_TOPIC = "input";

    private List<Integer> l1;

    private KafkaMessageListenerContainer<String, Integer> container;

    private BlockingQueue<ConsumerRecord<String, Integer>> records;

    private static final Logger LOGGER = LoggerFactory.getLogger(KafkaTest.class);

    @ClassRule
    public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, SENDER_TOPIC);

    @Before
    public void testTemplate() throws Exception {

        // set up the Kafka consumer properties
        Map<String, Object> consumerProperties = KafkaTestUtils.consumerProps("test-group", "false", embeddedKafka);
        consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, IntegerDeserializer.class);

        // create a Kafka consumer factory
        DefaultKafkaConsumerFactory<String, Integer> consumerFactory = new DefaultKafkaConsumerFactory<>(
                consumerProperties);

        // set the topic that needs to be consumed
        ContainerProperties containerProperties = new ContainerProperties(SENDER_TOPIC);

        // create a Kafka MessageListenerContainer
        container = new KafkaMessageListenerContainer<>(consumerFactory, containerProperties);

        // create a thread safe queue to store the received message
        records = new LinkedBlockingQueue<>();

        // setup a Kafka message listener
        container.setupMessageListener(new MessageListener<String, Integer>() {
            @Override
            public void onMessage(ConsumerRecord<String, Integer> record) {
                LOGGER.debug("test-listener received message='{}'", record.toString());
                records.add(record);
            }
        });

        // start the container and underlying message listener
        container.start();

        // wait until the container has the required number of assigned partitions
        ContainerTestUtils.waitForAssignment(container, embeddedKafka.getPartitionsPerTopic());

    }

    @After
    public void tearDown() {
        // stop the container
        container.stop();
    }

    @Test
    public void testSend() throws InterruptedException {
        // send the message
        Map<String, Object> producerProps = KafkaTestUtils.producerProps(embeddedKafka);
        producerProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        producerProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class);
        ProducerFactory<String, Integer> pf = new DefaultKafkaProducerFactory<>(producerProps);
        KafkaTemplate<String, Integer> template = new KafkaTemplate<>(pf);
        template.send(SENDER_TOPIC, i1);

        // check that the message was received
        ConsumerRecord<String, Integer> received = records.poll(10, TimeUnit.SECONDS);
        // Hamcrest Matchers to check the value
        assertThat(received, hasValue(i1));

        // AssertJ Condition to check the key
        assertThat(received, hasKey(null));

        System.out.println(received);
    }

}

谢谢,这是一个开始,但是对于我写的制片人来说,这仍然不起作用。这是测试的最终目标,请尝试将我的制作人整合到测试中。我拥有的生产者使用:
configProps.put(ProducerConfig.KEY\u SERIALIZER\u CLASS\u CONFIG,StringSerializer.CLASS);configProps.put(ProducerConfig.VALUE\u SERIALIZER\u CLASS\u CONFIG,JsonSerializer.CLASS)我尝试将我的消费者属性与之匹配,但仍然没有成功。请参阅我答案的编辑-您的制作人已连接到其他经纪人。连接制作人解决了我的问题。奇怪的是,当我更新Producer属性时,我得到了一个
org.apache.kafka.common.error
@Configuration
public class KafkaProducerConfig {

    @Value("${" + KafkaEmbedded.SPRING_EMBEDDED_KAFKA_BROKERS + ":localhost:9092}")
    private String bootstrapServer;

    @Bean
    public ProducerFactory<String, Integer> producerFactory() {
        Map<String, Object> configProps = new HashMap<>();
        configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServer);
        configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class);
        return new DefaultKafkaProducerFactory<>(configProps);
    }

    @Bean
    public KafkaTemplate<String, Integer> kafkaTemplate() {
        return new KafkaTemplate<>(producerFactory());
    }

}
@RunWith(SpringRunner.class)
@SpringBootTest
@DirtiesContext
public class KafkaTest {

    // in case I need to send some integers
    private final Integer i1 = 42;

    private final Integer i2 = 3;

    private static final String SENDER_TOPIC = "input";

    private List<Integer> l1;

    @Autowired
    private KafkaProducer producer;

    private KafkaMessageListenerContainer<String, Integer> container;

    private BlockingQueue<ConsumerRecord<String, Integer>> records;

    private static final Logger LOGGER = LoggerFactory.getLogger(KafkaTest.class);

    @ClassRule
    public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, SENDER_TOPIC);

    @Before
    public void testTemplate() throws Exception {

        // set up the Kafka consumer properties
        Map<String, Object> consumerProperties = KafkaTestUtils.consumerProps("test-group", "false", embeddedKafka);
        consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, IntegerDeserializer.class);

        // create a Kafka consumer factory
        DefaultKafkaConsumerFactory<String, Integer> consumerFactory = new DefaultKafkaConsumerFactory<>(
                consumerProperties);

        // set the topic that needs to be consumed
        ContainerProperties containerProperties = new ContainerProperties(SENDER_TOPIC);

        // create a Kafka MessageListenerContainer
        container = new KafkaMessageListenerContainer<>(consumerFactory, containerProperties);

        // create a thread safe queue to store the received message
        records = new LinkedBlockingQueue<>();

        // setup a Kafka message listener
        container.setupMessageListener(new MessageListener<String, Integer>() {
            @Override
            public void onMessage(ConsumerRecord<String, Integer> record) {
                LOGGER.debug("test-listener received message='{}'", record.toString());
                records.add(record);
            }
        });

        // start the container and underlying message listener
        container.start();

        // wait until the container has the required number of assigned partitions
        ContainerTestUtils.waitForAssignment(container, embeddedKafka.getPartitionsPerTopic());

    }

    @After
    public void tearDown() {
        // stop the container
        container.stop();
    }

    @Test
    public void testSend() throws InterruptedException {
        // send the message
        producer.send(i1);

        // check that the message was received
        ConsumerRecord<String, Integer> received = records.poll(10, TimeUnit.SECONDS);
        // Hamcrest Matchers to check the value
        assertThat(received, hasValue(i1));

        // AssertJ Condition to check the key
        assertThat(received, hasKey(null));

        System.out.println(received);
    }

}
ConsumerRecord(topic = input, partition = 1, offset = 0, CreateTime = 1519487134283, checksum = 866641474, serialized key size = -1, serialized value size = 4, key = null, value = 42)