Python: Getting mocked function value returned, not MagicMock, without adding returnvalue

Question:

So, basically I want to mock a function imported in another class, and for some reason I can’t retrieve the mocked result without calling returnvalue of the mock.

This is the setup: one file, one module, one test class. I want to mock functionB() in source.fileB.

source.fileB

def functionB():
    print('toto')

source.fileA

from source.fileB import *

def functionA():
    print("bar")
    return functionB()

Test case

from source.fileA import functionA
from source.fileA import functionB

@mock.patch('source.fileA.functionB')
def test_functionA(functionB_mock):
 functionB_mock().returnvalue = "foo"

 print(functionB_mock) # prints MagicMock object named functionB
 print(functionB_mock.returnvalue) # prints MagicMock object name functionB.returnvalue
 print(functionB_mock().returnvalue) #prints "foo"
 print(functionA().returnvalue) #executes functionA, prints both "bar" and "foo"
 print(functionA()) #executes functionA, prints both "bar" and MagicMock object named functionB()

So every time I try to get the result of the mocked functionB(), I have to use returnvalue. This is driving me nuts as I cannot update functionA() with

return functionB().returnvalue

in order for the rest of the code under test to execute properly.
I must be doing something wrong, but I can’t understand what precisely.

Asked By: Robin Castellon

||

Answers:

There are two problems:

  1. The mock attribute you want is return_value, not returnvalue!
  2. You need to set that attribute on the mock itself, not the result of calling the mock (which is a different mock).

Here’s a self-contained (single-file) version of your test code with the fix and some explanatory comments.

import mock


def functionB():
    print('toto')


def functionA():
    print("bar")
    return functionB()


@mock.patch('__main__.functionB')
def test_functionA(functionB_mock):
    functionB_mock.return_value = "foo"

    # Prints a mock object because that's what functionB_mock is.
    print(functionB_mock)

    # Prints "foo" because that's what functionB_mock returns.
    print(functionB_mock())

    # The following two lines would raise AttributeError because
    # "foo" isn't a Mock and doesn't have a 'return_value' attribute!
    # print(functionB_mock().return_value)
    # print(functionA().return_value)

    # Executes functionA, prints "bar" and "foo"
    print(functionA())


test_functionA()
Answered By: Samwise
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.