Mock: assert mock_calls с пустым массивом в качестве аргумента вызывает ValueError и np.testing.assert_array_equal не работает - PullRequest
0 голосов
/ 18 июня 2019

У меня есть макет объекта, который я хотел бы проверить его вызовы с помощью mock_calls, где он вызывается с numpy массивы . Но проблема в том, что он вызывает ValueError, как показано в следующем простом игрушечном примере.

>>> mocked_model_called_with_np_array = mock.Mock()
>>> mocked_model_called_with_np_array(np.array([1, 2]))
>>> mocked_model_called_with_np_array.mock_calls
[call(array([1, 2]))]

Теперь я установил ожидаемые звонки:

>>> expected_call_with_numpy = [mock.call(np.array([1, 2]))]

Теперь, если я проверю это, как показано ниже, возникает ошибка:

>>> assert expected_call_with_numpy == mocked_model_called_with_np_array.mock_calls

---------------------------------------------------------------------------
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-61-9806e62badf5> in <module>
----> 1 assert expected_call_with_numpy == mocked_model_called_with_np_array.mock_calls

c:\users\meysam.sadeghi\appdata\local\programs\python\python36\lib\unittest\mock.py in __eq__(self, other)
   2053 
   2054         # this order is important for ANY to work!
-> 2055         return (other_args, other_kwargs) == (self_args, self_kwargs)
   2056 
   2057 

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Мой поиск по stackoverflow и найденные решения:

ЗДЕСЬ предлагается использовать np.testing.assert_array_equal, пока у вас есть массивы numpy, но это также не решает мои проблемы, как показано ниже.

>>> np.testing.assert_array_equal(expected_call_with_numpy, mocked_model_called_with_np_array.mock_calls)

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-57-4a0373c94354> in <module>
----> 1 np.testing.assert_array_equal(expected_call_with_numpy, mocked_model_called_with_np_array.mock_calls)

c:\users\meysam.sadeghi\appdata\local\programs\python\python36\lib\site-packages\numpy\testing\utils.py in assert_array_equal(x, y, err_msg, verbose)
    852     __tracebackhide__ = True  # Hide traceback for py.test
    853     assert_array_compare(operator.__eq__, x, y, err_msg=err_msg,
--> 854                          verbose=verbose, header='Arrays are not equal')
    855 
    856 

c:\users\meysam.sadeghi\appdata\local\programs\python\python36\lib\site-packages\numpy\testing\utils.py in assert_array_compare(comparison, x, y, err_msg, verbose, header, precision, equal_nan, equal_inf)
    776                                 names=('x', 'y'), precision=precision)
    777             if not cond:
--> 778                 raise AssertionError(msg)
    779     except ValueError:
    780         import traceback

AssertionError: 
Arrays are not equal

(mismatch 100.0%)
 x: array([['', (array([1, 2]),), {}]], dtype=object)
 y: array([['', (array([1, 2]),), {}]], dtype=object)

Обратите внимание, что массивы одинаковы, но выдает ошибку!

Может кто-нибудь прокомментировать, как использовать mock_calls для объекта mockec, вызываемого с массивом numpy, а затем проверить, производят ли mock_calls ожидаемые вызовы? например, что-то вроде ниже

assert expected_call_with_numpy == mocked_model_called_with_np_array.mock_calls

1 Ответ

0 голосов
/ 15 июля 2019

Можно отследить бесчисленные аргументы, передаваемые любому методу класса, просто создав поддельный (фиктивный) класс.Например, если я хочу проверить пустые вызовы метода bar объекта класса Foo, я могу сделать следующее:

class MockFoo():
    called_by = []
    def bar(self, *args):
        self.called_by.extend([*args])

Теперь у нас есть:

>>> a = MockFoo()
>>> a.bar(numpy.array([1, 2]))
>>> a.bar(numpy.array([100, 200]))
>>> a.bar(numpy.array([10000, 20000]))

Теперь мы можем просто проверить вызовы на foo.bar, как показано ниже:

>>> a.called_by 
[array([1, 2]), array([100, 200]), array([10000, 20000])]
...