Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asserting an object passed into a mocked method in the python mock

Tags:

python

mocking

Say I have a class called Client that creates an object of the Request class and passes it to a method of a Connection object:

class Client(object):
    def __init__(self, connection):
        self._conn = connection

    def sendText(plaintext):
        self._conn.send(Request(0, plaintext))

And I want to assert the object passed into the Connection.send method to check its properties. I start with creating a mocked Connection class:

conn = Mock()

client = Client(conn)
client.sendText('some message')

And then I want something like:

conn.send.assert_called_with(
    (Request,
    {'type': 0, 'text': 'some message'})
)

Where 'type' and 'text' are properties of Request. Is there a way to do this in python's mock? All I found in the documentation were simple data examples. I could have done it with mock.patch decorator by replacing the original 'send' method with a method which asserts the object's fields:

def patchedSend(self, req):
    assert req.Type == 0

with mock.patch.object(Connection, 'send', TestClient.patchedSend):
    ...

but in this case I would have to define a separete mocked function for every method check and I couldn't check (without additional coding) if the function has been called at all.

like image 391
Nikita Kanashin Avatar asked Feb 15 '23 22:02

Nikita Kanashin


1 Answers

You can get the last arguments to the mock with

request, = conn.send.call_args

and then assert properties about that. If you want facilities to express more sophisticated assertions about things, you can install PyHamcrest.

Note: Don't use assert in unit tests. Use assertion methods like assertEqual or assertTrue. Assertion methods can't be accidentally turned off, and they can give more useful messages than assert statements.

like image 198
user2357112 supports Monica Avatar answered Feb 18 '23 13:02

user2357112 supports Monica