Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
712 views
in Technique[技术] by (71.8m points)

unit testing - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...