我正在使用python-mock来模拟文件打开调用.我希望能够以这种方式传递伪数据,因此我可以验证read()是否正在调用以及使用测试数据而无需在测试中访问文件系统.
这是我到目前为止所得到的:
file_mock = MagicMock(spec=file)
file_mock.read.return_value = 'test'
with patch('__builtin__.open', create=True) as mock_open:
mock_open.return_value = file_mock
with open('x') as f:
print f.read()
Run Code Online (Sandbox Code Playgroud)
正如我所假设<mock.Mock object at 0x8f4aaec>的'test'那样输出.我在构建这个模拟时做错了什么?
编辑:
看起来像这样:
with open('x') as f:
f.read()
Run Code Online (Sandbox Code Playgroud)
还有这个:
f = open('x')
f.read()
Run Code Online (Sandbox Code Playgroud)
是不同的对象.使用mock作为上下文管理器使它返回一个新的Mock,而直接调用它返回我已定义的内容mock_open.return_value.有任何想法吗?
我需要补丁os.listdir和其他os函数来测试我的Python函数.但是当它们被修补时,import声明失败了.是否可以仅在单个模块(真实模块)中修补此功能,并使tests.py正常工作?
这是一个打破的例子import:
import os
from mock import patch
# when both isdir and isfile are patched
# the function crashes
@patch('os.path.isdir', return_value=False)
@patch('os.path.isfile', return_value=False)
def test(*args):
import ipdb; ipdb.set_trace()
real_function(some_arguments)
pass
test()
Run Code Online (Sandbox Code Playgroud)
我想看real_function一个修补os.path,并测试看看正常的功能.
我想创建一个mock.Mock()对象,然后添加一个称为session实例方法的方法,该方法传递self对模拟对象的引用,允许该方法向模拟对象添加状态。这是可能的(无需手动使用types.MethodType,例如,使用模拟的内置 API),还是我应该找到解决方法?
请注意,我发现了这个问题,它是针对 Ruby 的,似乎涵盖了类似的内容,如果不是同一件事的话。不幸的是,我根本不了解 Ruby。
我最近开始在 python 中使用模拟框架。似乎如果我修补一个函数,则不会调用实际代码-这意味着未实现此实际函数所做的数据库更改等。我一直试图通过事先调用函数并存储返回值并将其作为 arg 传递到 patch() 来绕过它,但是有没有更好的方法来做到这一点?理想情况下,我想要一个可以用作 a 的代码,silent observer我可以简单地询问它是否observed调用了某个函数,调用了多少次,以及使用了哪些参数
return_val = funct()
# C: Now call me again and assert that these intensive computation functions are not called but taken from cache
with patch('funct', return_value=return_val) as mock_task:
me_response = self.client.get(me_url, format='json') #should fetch from cache
assert not mock_task.called
Run Code Online (Sandbox Code Playgroud) 我正在尝试为我正在编写的应用程序设置一个测试装置,其中我的一个类被模拟替换。我很高兴将模拟类的大部分属性保留为默认MagicMock实例(我只对它们的用法做出断言感兴趣),但该类还有一个属性,我想为其提供特定的返回值.
作为参考,这是我试图修补的类的大纲:
class CommunicationService(object):
def __init__(self):
self.__received_response = Subject()
@property
def received_response(self):
return self.__received_response
def establish_communication(self, hostname: str, port: int) -> None:
pass
def send_request(self, request: str) -> None:
pass
Run Code Online (Sandbox Code Playgroud)
我遇到的困难是,当我修补时CommunicationService,我还尝试为将返回特定值PropertyMock的received_response属性设置 a 。然而,当我在我的生产代码中实例化这个类时,我发现调用CommunicationService.received_response返回的是默认MagicMock实例而不是我希望它们返回的特定值。
在测试设置期间,我执行以下操作:
context.mock_comms_exit_stack = ExitStack()
context.mock_comms = context.mock_comms_exit_stack.enter_context(
patch('testcube.comms.CommunicationService', spec=True))
# Make 'received_response' observers subscribe to a mock subject.
context.mock_received_response_subject = Subject()
type(context.mock_comms).received_response = PropertyMock(return_value=context.mock_received_response_subject)
# Reload TestCube module to make it import the …Run Code Online (Sandbox Code Playgroud) 我有一个抽象基类:
import abc
import six
@six.add_metaclass(abc.ABCMeta)
class A(object):
@abc.abstractmethod
def f(self, arg1):
pass
Run Code Online (Sandbox Code Playgroud)
我想使用此类作为模拟的规范。
import mock
mock_a = mock.Mock(spec=A)
Run Code Online (Sandbox Code Playgroud)
这部分起作用。例如,mock_a.x结果为AttribureError("Mock object has no attribute 'x')。但是mock_a.f,并未基于的抽象方法进行说明A.f。无论传递给的参数数量如何,它都会返回一个模拟f。
mock_a = mock.Mock(spec=A)
# Succeeds
print mock_a.f(1)
# Should fail, but returns a mock
print mock_a.f(1,2)
# Correctly fails
print mock_a.x
Run Code Online (Sandbox Code Playgroud)
模拟可以创建speced一个模拟A.f带create_autospec...
f_spec = mock.create_autospec(A.f)
# Succeeds
f_spec(mock_a, 1)
# Correctly fails
f_spec(mock_a, 1, 2)
Run Code Online (Sandbox Code Playgroud)
...但是对于A的属性却不这样做
如何创建可以准确实现抽象基类的模拟?
我问如何使用Python3在单元测试中模拟类属性.我已经尝试了以下内容,这对我来说对文档很有意义,但它不起作用:
foo.py:
class Foo():
@property
def bar(self):
return 'foobar'
def test_foo_bar(mocker):
foo = Foo()
mocker.patch.object(foo, 'bar', new_callable=mocker.PropertyMock)
print(foo.bar)
Run Code Online (Sandbox Code Playgroud)
我已经安装pytest并pytest_mock运行了这样的测试:
pytest foo.py
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
> setattr(self.target, self.attribute, new_attr)
E AttributeError: can't set attribute
/usr/lib/python3.5/unittest/mock.py:1312: AttributeError
Run Code Online (Sandbox Code Playgroud)
我的期望是测试运行没有错误.
今天我意识到unittest.mock.patch如何导入函数很重要。取决于mock.patch呼叫工作或被忽略的使用方式。在 Python 中,我们通常导入一个函数:
import os或这样的导入语句from ... import ...像这样的声明from os import systemmock.patch如果我使用A就像一个魅力import os,但如果我修补了它,它会被忽略from os import system。
示例 1:使用导入
import os
from unittest import mock
def echo():
os.system('echo "Hello"')
with mock.patch('os.system') as mocked:
print(mocked)
mocked.side_effect = Exception('Patch works!')
echo()
Run Code Online (Sandbox Code Playgroud)
示例 1 的输出
<MagicMock name='system' id='140037358656760'>
Traceback (most recent call last):
File "/.../config/scratches/scratch_7.py", line 12, in <module>
echo()
File "/.../config/scratches/scratch_7.py", line 6, in echo
os.system('echo "Hello"')
File "/.../python3.5/unittest/mock.py", …Run Code Online (Sandbox Code Playgroud) 考虑这个例子:
模块.py:
class LST:
x = [1]
class T:
def __init__(self, times):
self.times = times
def t1(self):
return LST.x * self.times
def t2(self):
return LST.x * (self.times+1)
def t3(self):
return LST.x * (self.times+2)
Run Code Online (Sandbox Code Playgroud)
测试.py:
from mock import patch
import unittest
import module
@patch('module.LST')
class TestM(unittest.TestCase):
@classmethod
def setUpClass(cls):
super(TestM, cls).setUpClass()
cls.t = module.T(1)
def test_01(self, LST):
LST.x = [2]
self.assertEqual([2], self.t.t1())
def test_02(self, LST):
LST.x = [2]
self.assertEqual([2, 2], self.t.t2())
def test_03(self, LST):
LST.x = [2]
self.assertEqual([2, 2, 2], self.t.t3()) …Run Code Online (Sandbox Code Playgroud) 这是Django 1.6.8,Python 2.7和模拟库.
我有一个视图,使用suds调用远程服务销售税信息(这是一个简化版本):
def sales_tax(self, bundle_slug):
bundle = get_object_or_404(Bundle, slug=bundle_slug,
active=True)
cloud = TaxCloud(TAXCLOUD_API_ID, TAXCLOUD_API_KEY)
origin = Address('origin address')
destination = Address('customer address')
cart_item = CartItem(bundle.sku, TAXCLOUD_TIC_ONLINE_GAMES,
bundle.price, 1)
try:
rate_info = cloud.get_rate(origin, destination,
[cart_item],
str(customer.id))
sales_tax = Decimal(rate_info['sales_tax'])
response = {'salesTax': locale.currency(sales_tax),
'total': locale.currency(bundle.price + sales_tax)}
except TaxCloudException as tce:
response = {
'error': str(tce)
}
Run Code Online (Sandbox Code Playgroud)
以下是该TaxCloud课程的相关代码:
from suds.client import Client
from suds import WebFault
class TaxCloud(object):
def __init__(self, api_login_id, api_key):
self.api_login_id = api_login_id …Run Code Online (Sandbox Code Playgroud) python ×10
python-mock ×10
mocking ×3
python-3.x ×3
django ×2
pytest ×2
abc ×1
patch ×1
tdd ×1
unit-testing ×1