How can I claim calls that take sequence arguments with Python Mock?

I am processing a sequence of custom objects. It looks something like this:

class Thing(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

The method I'm testing now has the following functions:

def my_function(things):
    x_calc = calculate_something(t.x for t in things)
    y_calc = calculate_something(t.y for t in things)
    return x_calc / y_calc

The problem I am facing is testing calls on calculate_something. I want to say that these calls have occurred, something like this:

calculateSomethingMock.assert_any_call(the_sequence)

, calculate_something, , . set, , , calculate_something. . , , .

, ?

Python 2.7.3 Mock 1.0.1.

( , , , .)

Edit:

, " " , , calculate_something.

+5
2

, , . , , . , : -, , , . / . , . , , : " calculate_something". .

+2

Mock, call_args_list, , .

, calculate_something .

calculate_something = Mock(return_value=None)

my_function :

calculate_something.call_args_list

( ).

Edit:

(, , Python3.3 )

mymodule.py

class Thing:
    ...
def calculate_something:
    ...

def my_function(things):
    # Create the list outside in order to avoid a generator object
    # from being passed to the Mock object.

    xs = [t.x for t in things]
    x_calc = calculate_something(xs)

    ys = [t.y for t in things]
    y_calc = calculate_something(ys)
    return True

test_file.py

import unittest
from unittest.mock import patch, call
import mymodule



class TestFoo(unittest.TestCase):

    # You can patch calculate_something here or
    # do so inside the test body with 
    # mymodule.calcualte_something = Mock()
    @patch('mymodule.calculate_something')
    def test_mock(self, mock_calculate):

        things = [mymodule.Thing(3, 4), mymodule.Thing(7, 8)]

        mymodule.my_function(things)

        # call_args_list returns [call([3, 7]), call([4, 8])]
        callresult = mock_calculate.call_args_list


        # Create our own call() objects to compare against
        xargs = call([3, 7])
        yargs = call([4, 8])

        self.assertEqual(callresult, [xargs, yargs])

        # or
        # we can extract the call() info
        # http://www.voidspace.org.uk/python/mock/helpers.html#mock.call.call_list
        xargs, _ = callresult[0]
        yargs, _ = callresult[1]

        xexpected = [3, 7]
        yexpected = [4, 8]

        self.assertEqual(xargs[0], xexpected)
        self.assertEqual(yargs[0], yexpected)

if __name__ == '__main__':
    unittest.main()
+7

All Articles