Search code examples
unit-testingpython-2.7mockingpython-mock

python mock patch : a method of instance is called?


In python 2.7, I have this function

from slacker import Slacker


def post_message(token, channel, message):
    channel = '#{}'.format(channel)

    slack = Slacker(token)
    slack.chat.post_message(channel, message)

with mock and patch, I can check that the token is used in Slacker class

import unittest
from mock import patch

from slacker_cli import post_message


class TestMessage(unittest.TestCase):

    @patch('slacker_cli.Slacker')
    def test_post_message_use_token(self, mock_slacker):
        token = 'aaa'
        channel = 'channel_name'
        message = 'message string'

        post_message(token, channel, message)

        mock_slacker.assert_called_with(token)

how I can check the string use in post_message ?

I try with

mock_slacker.chat.post_message.assert_called_with('#channel_name') 

but I get

AssertionError: Expected call: post_message('#channel_name')
Not called

Solution

  • You need to be specific about where the call is taking place. The code is:

    slack.chat.post_message
    

    So, as slack is an instance of the mocked class Slacker, you'll need to use return_value to ensure you're talking about that instance:

    mock_slacker.return_value.chat.post_message.assert_called_with
    

    You've patched 'slacker_cli.Slacker' so mock_slacker is a patched class. The call itself is taking place on an instance of that patched class. Calling a class returns an instance, hence the use of return_value.