2

I'm using the mock library to patch a class in a program that connects to a external resource and sends a dictioanry.

The structure goes a litle like this...

code.py

def make_connection():
    connection = OriginalClass(host, port)
    connection.connect()
    connection.send(param)
    connection.close()

test.py

@mock.path('code.OriginalClass')
def test_connection(self, mocked_conn):
    code.make_connection()
    mocked_conn.assert_called_with(host, port)
    mocked_conn.connect.assert_called_once()
    mocked_conn.send.assert_called_with(param)

The first assert_called_with works perfectly, but the calls to method of the mocked class don't pass. I have tried using patch.object as a decorator also with no luck.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
cllamach
  • 441
  • 3
  • 14

1 Answers1

3

The connect() and send() methods are called on the return value of the first call; adjust your test accordingly:

mocked_conn.return_value.connect.assert_called_once()
mocked_conn.return_value.send.assert_called_with(param)

I usually store a reference to the 'instance' first:

@mock.path('code.OriginalClass')
def test_connection(self, mocked_conn):
    code.make_connection()
    mocked_conn.assert_called_with(host, port)
    mocked_instance = mocked_conn.return_value
    mocked_instance.connect.assert_called_once()
    mocked_instance.send.assert_called_with(param)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Incredible, i can't believe i didn't see that. Can i upvote this over 9000? Thanks a huge steaming pile of lots. :D I'm going to start keeping that reference from now on, avoiding headaches like this again. – cllamach Oct 13 '14 at 15:39