Akash Pagar
Akash Pagar

Reputation: 637

How to set mocked instance variable of class in python?

I'm writing a unit test for MyProducer class which produces the message on kafka topic. logic of testing is just mock the constructor of MyProducer class and set the manually created producer object to the instance of MyProducer class and then just verify if library methods of confluent-kafka are getting called correctly or not. I'm stuck in setting the manually created producer object to MyProducer. How can we set the manually created object to instance variable of MyClass by mocking init?

# kafka_producer.py # actual code

class MyProducer(object):
    def __init__(self, config: Dict[str, Any]={}):
        self.producer = Producer(config)
    def produce(self, *args, **kwargs):
        pass

# test_kafka.py # testing
       
def get_producer(*args, **kwargs):
    print(args,kwargs)
    conf = {
        "bootstrap.servers": 'localhost:9093'
    }
    producer = Producer(conf)


def produce(*args, **kwargs):
    pass


class KafkaTest(unittest.TestCase):

    def setUp(self):
        pass

    @mock.patch(
        "utils.kafka_producer.MyProducer.__init__",
    )
    @mock.patch(
        "confluent_kafka.Producer.produce",
    )

    def test_kafka_producer(self, produce, kafka_producer):

        produce.side_effect = produce

        kafka_producer.side_effect = get_producer

        kafkaProducer = MyProducer(
            {'bootstrap.servers': os.environ['KAFKA_BOOTSTRAP_SERVERS']}
        )

        kafkaProducer.produce(fake_kafka_topic, value='test_data')

It is giving error: AttributeError on 'MyProducer' has no attribute 'producer'.

Upvotes: 1

Views: 395

Answers (1)

Hasan
Hasan

Reputation: 968

I would suggest mocking Producer instead of MyProducer. Like

 @mock.patch("utils.kafka_producer.Producer")

If you are using any method like send of Producer the, then set a mocked/faked return value of kafka_producer as following:

kafka_producer.send.return_value = {"foo": "bar"}

Hopefully, this will serve your purpose.

Upvotes: 1

Related Questions