Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking Functions Using Python Mock

I am trying to Mock a function (that returns some external content) using the python mock module.

I'm having some trouble mocking functions that are imported into a module.

For example, in util.py I have

def get_content():   return "stuff" 

I want to mock util.get_content so that it returns something else.

I am trying this:

util.get_content=Mock(return_value="mocked stuff") 

If get_content gets invoked inside another module, it never actually seems to return the mocked object. Am I missing something in terms of how to use Mock?

Note that if I invoke the following, things work correctly:

>>> util.get_content=Mock(return_value="mocked stuff") >>> util.get_content() "mocked stuff" 

However, if get_content is called from inside another module, it invokes the original function instead of the mocked version:

>>> from mymodule import MyObj >>> util.get_content=Mock(return_value="mocked stuff") >>> m=MyObj() >>> m.func() "stuff" 

Contents of mymodule.py

from util import get_content  class MyObj:         def func():         get_content() 

So I guess my question is - how do I get invoke the Mocked version of a function from inside a module that I call?

It appears that the from module import function may be to blame here, in that it doesn't point to the Mocked function.

like image 846
shreddd Avatar asked Mar 12 '11 23:03

shreddd


People also ask

How do you mock a function in Python?

How do we mock in Python? Mocking in Python is done by using patch to hijack an API function or object creation call. When patch intercepts a call, it returns a MagicMock object by default. By setting properties on the MagicMock object, you can mock the API call to return any value you want or raise an Exception .

How do you use mocking in Pytest?

Test Code with pytest-mock to Simulate Response First, we need to import pytest (line 2) and call the mocker fixture from pytest-mock (line 5). On lines 12–14, the run() method of the Driver class was patched with a pre-programmed response to simulate an actual response.

How do you use mock exception in Python?

Just assign the exception to side_effect instead: mockedObj. raiseError. side_effect = Exception("Test") . You don't have to no: and his edit has a third way of doing it where he is making a Mock with the side effect set, but its still a valid, and good thing to know how to do in testing.

What is the difference between mock and MagicMock?

With Mock you can mock magic methods but you have to define them. MagicMock has "default implementations of most of the magic methods.". If you don't need to test any magic methods, Mock is adequate and doesn't bring a lot of extraneous things into your tests.


1 Answers

I think I have a workaround, though it's still not quite clear on how to solve the general case

In mymodule, if I replace

from util import get_content  class MyObj:         def func():         get_content() 

with

import util  class MyObj:         def func():         util.get_content() 

The Mock seems to get invoked. It looks like the namespaces need to match (which makes sense). However, the weird thing is that I would expect

import mymodule mymodule.get_content = mock.Mock(return_value="mocked stuff") 

to do the trick in the original case where I am using the from/import syntax (which now pulls in get_content into mymodule). But this still refers to the unmocked get_content.

Turns out the namespace matters - just need to keep that in mind when writing your code.

like image 63
shreddd Avatar answered Sep 29 '22 09:09

shreddd