tanaka
tanaka

Reputation: 401

Python calling mock with "=" not called result

I am trying to mock the following call:

df_x = method() # returns a pandas dataframe
df_x.loc[df_x['atr'] < 0, 'atr'] = 0

I have mocked the method so it returns a MagicMock and set a default value to the __ getitem__ attribute of the MagicMock as like this:

mock_df_x = mock_method.return_value
mock_df_x.__getitem__.return_value = 0

The problem is when I try asserting the call:

mock_df_x.loc.__getitem__.assert_called_with(False, 'atr')

I get a function not called error. If I call the function like this without the "= 0" part the assertion works.

df_x.loc[df_x['atr'] < 0, 'atr']

Upvotes: 2

Views: 217

Answers (1)

Samuel Dion-Girardeau
Samuel Dion-Girardeau

Reputation: 3180

The reason you are seeing this different behavior depending on whether on you have = 0 at the end of the call you are testing is that in Python's data model, those correspond to two different magic methods: __getitem__ and __setitem__.

This makes sense, because for example doing some_dictionary['nonexistent_key]' raises KeyError, whereas some_dictionary['nonexistent_key]' = 1 doesn't, and sets the value as expected.

Now, in order to fix your test, you only need to change your assertion from:

mock_df_x.loc.__getitem__.assert_called_with((False, 'atr'))

which only works if you are accessing the key, to:

mock_df_x.loc.__setitem__.assert_called_with((False, 'atr'), 0)

which works if you are trying to assign a value to that key. Notice the extra parameter, too, corresponding to the value you are actually trying to assign.

Upvotes: 1

Related Questions