Python Mock - How to get the return of a MagicMock as if it was a normal method

mocking, python, python-mock, python-unittest, unit-testing

Solution

If you trying to test if `MyClass.foo()` works correctly, you should not mock it.

Mocking is used for anything outside the code-under-test; if `foo` called another, external function `some_module.bar()`, then you'd mock `some_module.bar()` and give it a staged return value:

import some_module

class MyClass(object):
    def foo(self, x, y, z):
        result = some_module.bar(x, y, z)
        return result[0] + 2, result[1] * 2, result[2] - 2

class TestMyClass(TestCase):
    @mock.patch('some_module.bar')
    def test_myclass(self, mocked_bar):
        mocked_bar.return_value = (10, 20, 30)

        mc = MyClass()

        # calling MyClass.foo returns a result based on bar()
        self.assertEquals(mc.foo('spam', 'ham', 'eggs'),
            (12, 40, 28))
        # some_class.bar() was called with the original arguments
        mocked_bar.assert_called_with('spam', 'ham', 'eggs')

Here I set `mocked_bar.return_value` to what should be returned when the mocked `some_module.bar()` function is called. When the code-under-test actually calls `bar()`, the mock returns that value.

When you don't set a `return_value` a new `MagicMock()` object is returned instead, one that'll support further calls, and you can test for those calls just like on the `mocked_bar` object, etc.

Problem

For example: ``` import mock class MyClass(object): def foo(self, x, y, z): return (x, y, z) class TestMyClass(TestCase) @mock.patch('MyClass') def TestMyClass(self, MyClassMock): foo_mock = MyClassMock.foo() self.assertEquals((x, y, z), foo_mock) ``` So, the real question is: How to get the return of that test intead of getting this `<MagicMock name='MyClass.foo()' id='191728464'>` or how to deal with this MagicMock object to get the return of that test which should be a tuple containing 3 elements and nothing more or less? Any suggestion, any idea, any argument will be welcome. Thanks in advance!

Original source