7

I'm new to Python and I'm trying to mock a function only when a specific argument is passed. If other than the desired argument is passed, I'd like to call the original function instead.

In Python 2.7 I tried something like this:

from foo import config def test_something(self): original_config = config # config is a Module. def side_effect(key): if key == 'expected_argument': return mocked_result else: return original_config.get(key) config.get = Mock(side_effect=side_effect) # actualy_test_something... 

It won't work 'cause original_config is not a copy of config. It references the same module ending up in an infinite loop. I could try cloning the original config module instead but that seems to be overkill.

Is there something similar to RSpec's mocks I could use? e.g:

obj.stub(:message).with('an_expected_argument').and_return('a_mocked_result')

Any help would be appreciated. Thanks.

3
  • 3
    Is the indentation correct on config.get = Mock... line? Commented Sep 19, 2017 at 8:52
  • @PetrGladkikh yup it's correct. Commented Nov 11, 2017 at 0:13
  • 1
    Then I do not understand how it is executed. Both branches of if above it end with return so this line does not seem to be ever reached. Commented Nov 12, 2017 at 10:33

1 Answer 1

14

You'd need to store a reference to the unpatched function first:

def test_something(self): original_config_get = config.get def side_effect(key): if key == 'expected_argument': return mocked_result else: return original_config_get(key) config.get = Mock(side_effect=side_effect) 

Here original_config_get references the original function before you replaced it with a Mock() object.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.