Changed the titel to a more common one. I guess the problem is not that class specific.
I want to mock google.cloud.pubsub_v1.SubscriberClient I want to set a fake return value when calling the pull function of the client.
prod code: from google.cloud import pubsub_v1
def open_subscription() -> None: with pubsub_v1.SubscriberClient() as subscriber: logger.info(f'Listening for messages on {config.SUBSCRIPTION_NAME}', {'operation': {'first': True}}) while True: # get messages response = subscriber.pull( request = { 'subscription': config.SUBSCRIPTION_NAME, 'max_messages': config.MAX_MESSAGES } ) from the prod code above I want to set the return value for calling the pull method. I am creating a pull-response object in the test code.
test code:
import unittest from unittest.mock import MagicMock, patch from app.pubsub import pubsub_service from google import pubsub_v1 import json class TestPubSubService(unittest.TestCase): def create_test_message(self): message_string = '{"testKey": "testValue"}' message_json = json.dumps(message_string, indent=2) message_data = message_json.encode('utf-8') pubsub_message = pubsub_v1.PubsubMessage() pubsub_message.data = message_data received_message = pubsub_v1.ReceivedMessage() received_message.ack_id = "testId" received_message.message = pubsub_message return received_message def create_test_pull_response(self, received_message): pull_response = pubsub_v1.PullResponse() pull_response.received_messages = [received_message] return pull_response @patch('app.pubsub.pubsub_service.pubsub_v1.SubscriberClient') def test_open_subscription(self, mock_subscriber): test_message = self.create_test_message() pull_response = self.create_test_pull_response(test_message) mock_subscriber.return_value.pull.return_value = MagicMock(return_value = pull_response) pubsub_service.open_subscription() At least the MagicMock is in place (without using the patch the real subscriber is in place). So basically I would say I mocked the subscriberClient. But I cannot set the return_value for calls to the pull method. But there wont be a pull retur value. All I get is another magicMock created.
I do not get it why it is not working. As most stuff I read we usually have to call 'return_value' on the mock, append the name of either the field or function to be set, append that ones 'return_value' and set a value viea MagicMock. The format should be: mockFirst.return_value.second.return_value.third.return_value = Mock(return_value = the_value_to_return)
Hopefully you can explain me what I am doing wrong. Thanks.
edit: tried also the following ones which where the answers in other posts: Mocking Method Calls In Python Mock a method of a mocked object in Python?
mock_subscriber.pull.return_value = pull_response mock_subscriber.return_value.pull.return_value = pull_response none seems to work. the return value of the pull method stays to be a magicMock.
And this is how it looks like in debugging (hovering over response): 