python class 方法模拟失败
python class method mocking failure
试图理解 mocking/patching 并且我有一个包含三个文件的 restful API 项目(仅供参考,我正在使用 flask)
- class1.py
- domain.py
- test_domain.py
class1.py 文件内容:
class one:
def addition(self):
return 4+5
domain.py 文件内容:
from class1 import one
class DomainClass(Resource):
def post(self):
test1 = one()
val = test1.addition()
return {'test' : val }
test_domain.py文件内容:
import my_app
from flask_api import status
from mock import patch
app = my_app.app.test_client()
def test_post():
with patch('domain.one') as mock:
instance = mock.return_value
instance.addition.return_value = 'yello'
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
assert mock.called
对于我的 test_domain.py 文件,我也试过这个...
@patch('domain.one')
def test_post(mock_domain):
mock_domain.addition.return_value = 1
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
我对 200 次通过状态的断言,但是,问题是我无法模拟或修补加法方法来给我值 1 代替 9 (4+5)。我也试过 'assert mock.called' 但它也失败了。我知道我应该在使用 'one()' 方法的 mocking/patching 中,即在 domain.py 中而不是在 class1.py 中。但是我什至尝试用 class1.one 代替 domain.one,但我仍然得到 9 而不是 1。我做错了什么?
******** 更新
我在同一问题上遇到了另一个难题,我尝试在 test_domain 文件中执行此操作而不是修补....
from common.class1 import one
def test_post():
one.addition = MagicMock(return_value=40)
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
问题
在上面的更新中,我没有在使用它的地方做模拟(即:domain.one.addition = MagicMock(...) 它仍然有效!! !! 看来它可能正在做一个全球性的变化。为什么会这样?
在上面的例子中,'one'是模块class1.py中的一个class。如果我将此 class 'one' 更改为 class1.py 中的函数,模拟将不起作用。似乎这个驻留在模块 class1.py 中的函数 'one' 不能像这样被模拟...one.return_value = 'xyz',为什么?可以全局模拟吗?
您的代码中存在一些问题。在第一个示例中,您忘记了 patch()
应用于 with
上下文,并且在上下文结束时恢复了原始代码。按照代码应该工作:
def test_post():
with patch('domain.one') as mock:
instance = mock.return_value
instance.addition.return_value = 'yello'
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
assert mock.called
assert response.data['test'] == 'yello'
第二个还有一个问题:如果你只想要补丁 addition
你应该使用的方法:
@patch('domain.one.addition')
def test_post(mock_addition):
mock_addition.return_value = 1
...
assert mock_addition.called
assert response.data['test'] == 1
如果你想模拟 all one
class 你应该设置 addition
方法的 return 值 模拟实例 return 由 mock_domain
调用 编辑,就像您的第一个示例:
@patch('domain.one')
def test_post(mock_domain):
mock_addition = mock_domain.return_value.addition
mock_addition.return_value = 1
...
assert mock_addition.called
assert response.data['test'] == 1
试图理解 mocking/patching 并且我有一个包含三个文件的 restful API 项目(仅供参考,我正在使用 flask)
- class1.py
- domain.py
- test_domain.py
class1.py 文件内容:
class one:
def addition(self):
return 4+5
domain.py 文件内容:
from class1 import one
class DomainClass(Resource):
def post(self):
test1 = one()
val = test1.addition()
return {'test' : val }
test_domain.py文件内容:
import my_app
from flask_api import status
from mock import patch
app = my_app.app.test_client()
def test_post():
with patch('domain.one') as mock:
instance = mock.return_value
instance.addition.return_value = 'yello'
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
assert mock.called
对于我的 test_domain.py 文件,我也试过这个...
@patch('domain.one')
def test_post(mock_domain):
mock_domain.addition.return_value = 1
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
我对 200 次通过状态的断言,但是,问题是我无法模拟或修补加法方法来给我值 1 代替 9 (4+5)。我也试过 'assert mock.called' 但它也失败了。我知道我应该在使用 'one()' 方法的 mocking/patching 中,即在 domain.py 中而不是在 class1.py 中。但是我什至尝试用 class1.one 代替 domain.one,但我仍然得到 9 而不是 1。我做错了什么?
******** 更新 我在同一问题上遇到了另一个难题,我尝试在 test_domain 文件中执行此操作而不是修补....
from common.class1 import one
def test_post():
one.addition = MagicMock(return_value=40)
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
问题
在上面的更新中,我没有在使用它的地方做模拟(即:domain.one.addition = MagicMock(...) 它仍然有效!! !! 看来它可能正在做一个全球性的变化。为什么会这样?
在上面的例子中,'one'是模块class1.py中的一个class。如果我将此 class 'one' 更改为 class1.py 中的函数,模拟将不起作用。似乎这个驻留在模块 class1.py 中的函数 'one' 不能像这样被模拟...one.return_value = 'xyz',为什么?可以全局模拟吗?
您的代码中存在一些问题。在第一个示例中,您忘记了 patch()
应用于 with
上下文,并且在上下文结束时恢复了原始代码。按照代码应该工作:
def test_post():
with patch('domain.one') as mock:
instance = mock.return_value
instance.addition.return_value = 'yello'
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
assert mock.called
assert response.data['test'] == 'yello'
第二个还有一个问题:如果你只想要补丁 addition
你应该使用的方法:
@patch('domain.one.addition')
def test_post(mock_addition):
mock_addition.return_value = 1
...
assert mock_addition.called
assert response.data['test'] == 1
如果你想模拟 all one
class 你应该设置 addition
方法的 return 值 模拟实例 return 由 mock_domain
调用 编辑,就像您的第一个示例:
@patch('domain.one')
def test_post(mock_domain):
mock_addition = mock_domain.return_value.addition
mock_addition.return_value = 1
...
assert mock_addition.called
assert response.data['test'] == 1