简体   繁体   English

Python Kafka mocking Kafka Consumer 的返回类型

[英]Python Kafka mocking return type of Kafka Consumer

I want to test a script when I use kafka-python package.我想在使用kafka-python package 时测试一个脚本。 I want to test type of return object for function我想测试 function 的返回类型 object

def _get_kafka_consumer() -> KafkaConsumer:
    consumer = KafkaConsumer(bootstrap_servers=_KAFKA_BOOTSTRAP_SERVICE,
                             auto_offset_reset='earliest')
    consumer.subscribe([_KAFKA_TOPIC_INPUT])
    return consumer

My test class looks like我的测试 class 看起来像

class TestVoiceToText(unittest.TestCase):

    def test_get_kafka_consumer_output_type(self):
        result = _get_kafka_consumer()
        self.assertIsInstance(result, KafkaConsumer)

and of course it does not pass because there is no Kafka Cluster running so KafkaConsumer cannot be created.当然它没有通过,因为没有运行 Kafka 集群,因此无法创建KafkaConsumer How can I mock that returning of KafkaConsumer(...) is of type KafkaConsumer without actual need of calling the actual constructor?我如何模拟KafkaConsumer(...)的返回是KafkaConsumer类型而不实际需要调用实际的构造函数?

I managed to solve the problem by using patch function from unittest.mock package:我设法通过使用来自unittest.mock package 的patch function 解决了这个问题:

    def test_get_kafka_consumer_output_type(self):
        with patch('voice_to_text.kafka_connector.KafkaConsumer') as kafka_consumer_class_mock:
            kafka_consumer_instance = _get_kafka_consumer()
            kafka_consumer_class_mock_instance = kafka_consumer_class_mock.return_value

            kafka_consumer_class_mock.assert_called_once()
            self.assertEquals(kafka_consumer_class_mock_instance, kafka_consumer_instance)

It only checks if a result of _get_kafka_consumer() is actually an object returned by calling a function KafkaConsumer() .它只检查_get_kafka_consumer()的结果是否实际上是调用 function KafkaConsumer()返回的 object。 We don't care what actually that function is doing.我们不在乎 function 实际上在做什么。

You would want the concept of spec in mocking.您可能需要 mocking 中的spec概念。 You can use autospec here I believe with success.我相信你可以在这里使用autospec成功。 Speccing will limit your mock to the original API of the object you're mocking, and allow it to pass isinstance tests as well.规范会将您的模拟限制为 object 的原始 API 您是 mocking,并允许它通过isinstance测试。 Here's the documentation on Autospeccing: https://docs.python.org/3.3/library/unittest.mock.html#autospeccing这是关于 Autospeccing 的文档: https://docs.python.org/3.3/library/unittest.mock.html#autospeccing

Here's how I'd do your test:这是我如何做你的测试:

 @mock.patch('voice_to_text.kafka_connector.KafkaConsumer', autospec=True)
 def test_get_kafka_consumer_output_type(self, kafka_consumer_mock):
        kafka_consumer_instance = _get_kafka_consumer()
        
        kafka_consumer_mock.assert_called_once_with(
            bootstrap_servers=_KAFKA_BOOTSTRAP_SERVICE,
            auto_offset_reset='earliest')
        kafka_consumer_mock.return_value.subscribe.assert_called_once_with(
            [_KAFKA_TOPIC_INPUT])
        kafka_consumer_mock.assert_called_once()

        self.assertEquals(kafka_consumer_mock.return_value, kafka_consumer_instance)
        self.assertIsInstance(kafka_consumer_instance, KafkaConsumer)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM