我想使用unittest测试一个使用上下文管理器从文件读取的方法:
with open(k_file, 'r') as content_file:
content = content_file.read()
Run Code Online (Sandbox Code Playgroud)
我不想在我的系统上创建一个文件,所以我想嘲笑它,但我现在并没有太大的成功.我发现了mock_open,但我真的不明白我应该如何使用它并在我的测试用例中将mock作为content_file提供.这里有这篇文章,但是我不明白在不修改原始代码的情况下如何在测试用例中编写这个.
有人能指出我正确的方向吗?
我想创建一个模拟方法来调用被模拟的底层方法。
我正在想象类似以下内容,但我找不到任何关于持有对被模拟对象的引用的模拟对象的文档,我已将其表示[[wrapped_method_foo]]如下:
from mock import patch
class Foo(object):
def __init__(self, state):
self.state = state
def foo(self, a):
print "real foo", a
return a + self.state
f = Foo(2000)
f.foo(1)
with patch.object(Foo, 'foo', autospec=True) as mock_foo:
def side_effect(self, a):
print "mock foo", a
return mock_foo.[[wrapped_method_foo]](self, a*2)
mock_foo.side_effect = side_effect
f.foo(2)
Run Code Online (Sandbox Code Playgroud) 我已经探索模拟和 pytest 几天了。
我有以下方法:
def func():
if not os.path.isdir('/tmp/folder'):
os.makedirs('/tmp/folder')
Run Code Online (Sandbox Code Playgroud)
为了对其进行单元测试,我决定修补 os.path.isdir 和 os.makedirs,如下所示:
@patch('os.path.isdir')
@patch('os.makedirs')
def test_func(patch_makedirs, patch_isdir):
patch_isdir.return_value = False
assert patch_makedirs.called == True
Run Code Online (Sandbox Code Playgroud)
无论 patch_isdir 的返回值如何,断言都会失败。有人可以帮我弄清楚我哪里出了问题吗?
我试图在一个类中修补多个方法。这是我的简化设置
Hook.py定义为
class Hook():
def get_key(self):
return "Key"
def get_value(self):
return "Value"
Run Code Online (Sandbox Code Playgroud)
HookTransfer.py定义为
from Hook import Hook
class HookTransfer():
def execute(self):
self.hook = Hook()
key = self.hook.get_key()
value = self.hook.get_value()
print(key)
print(value)
Run Code Online (Sandbox Code Playgroud)
我想模拟Hook类中的方法get_key和get_value。以下作品,即打印New_Key和New_Value
from HookTransfer import HookTransfer
import unittest
from unittest import mock
class TestMock(unittest.TestCase):
@mock.patch('HookTransfer.Hook.get_key', return_value="New_Key")
@mock.patch('HookTransfer.Hook.get_value', return_value="New_Value")
def test_execute1(self, mock_get_key, mock_get_value):
HookTransfer().execute()
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
但是,事实并非如此。它打印<MagicMock name='Hook().get_key()' id='4317706896'>并<MagicMock name='Hook().get_value()' id='4317826128'>
from HookTransfer import HookTransfer
import unittest
from unittest import mock
class TestMock(unittest.TestCase):
@mock.patch('HookTransfer.Hook', …Run Code Online (Sandbox Code Playgroud) 我有一个 Django 测试,我需要模拟 datetime.now(),因为它测试的视图使用 datetime.now()
\n\n我正在使用 Michael Foord 的模拟库,版本 1.0.1。
\n我正在寻找一种不使用其他库(例如 freezegun)的解决方案。
大多数例子都是这样的,这个导入 datetime 并覆盖它,但我正在导入 datetime.datetime 并尝试覆盖它,由于某种原因,这不起作用。
\n\n覆盖日期时间的工作原理:
\n\nimport mock\nimport datetime\n\nclass FixedDate(datetime.datetime):\n\n @classmethod\n def now(cls):\n return cls(2010, 1, 1)\n\n@mock.patch(\'datetime.datetime\', FixedDate)\ndef myTest():\n print(datetime.datetime.now())\n\nmyTest()\nRun Code Online (Sandbox Code Playgroud)\n\n但我想导入 datetime.datetime 并执行以下操作:
\n\nimport mock\nfrom datetime import datetime\n\nclass FixedDate(datetime):\n\n @classmethod\n def now(cls):\n return cls(2010, 1, 1)\n\n@mock.patch(\'datetime\', FixedDate)\ndef myTest():\n print(datetime.now())\n\nmyTest()\nRun Code Online (Sandbox Code Playgroud)\n\n这会导致 TypeError: Need a valid target to patch. 您提供了:“日期时间”。
\n\n模拟库还指出:
\n\n\ntarget 应该是 \xe2\x80\x98package.module.ClassName\xe2\x80\x99 形式的字符串。目标被导入,指定的对象被新对象替换,因此目标必须可以从您调用补丁的环境中导入。
\n …
我如何使用 python 模拟 python 方法unittest.mock,它将返回作为参数传递的相同值,
我试过,
from unittest.mock import MagicMock
def dummy_function(value):
"Will return same value as value passed to the function"
return value
# To moke gettext function used in template
# Then I pass this mock method to Jinja2 template to moke gettext string
_ = MagicMock(return_value=dummy_function)
Run Code Online (Sandbox Code Playgroud)
当我打印 jinja 模板时,它会显示如下所示的测试,
<div class="order_details">\n
<legend class="badge"><function dummy_function at 0x10887f730></legend>\n
</div>\n
Run Code Online (Sandbox Code Playgroud)
原始 Jinja2 模板有
<div class="order_details">
<legend class="badge">_('Details')</legend>
</div>
Run Code Online (Sandbox Code Playgroud) 我正在与 django 模拟作斗争;我什至简化了单元测试,但测试仍然失败。我想验证是否调用了一个方法(即使使用任何参数),但“assert_used_once_with”始终返回 False。目前我正在尝试:
@patch('utils.make_reset_password')
def test_shouldHaveCalledMakeResetToken(self, mocked):
user = User.get(...)
make_reset_password(user)
mocked.assert_called_once_with(user)
Run Code Online (Sandbox Code Playgroud)
即使这个简单的例子也失败了:
AssertionError: Expected 'make_reset_password' to be called once. Called 0 times
Run Code Online (Sandbox Code Playgroud)
这怎么可能?我究竟做错了什么?
提前致谢
这个问题与这个问题直接相关,但那个现在似乎已经过时了。
我正在尝试测试视图而无需访问数据库。为此,我需要对RelatedManager用户进行模拟。
我正在使用pytest和pytest-mock。
模型.py
# truncated for brevity, taken from django-rest-knox
class AuthToken(models.Model):
user = models.ForeignKey(
User,
null=False,
blank=False,
related_name='auth_token_set',
on_delete=models.CASCADE
)
Run Code Online (Sandbox Code Playgroud)
视图.py
class ChangeEmail(APIView):
permission_classes = [permissions.IsAdmin]
serializer_class = serializers.ChangeEmail
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = request.user
user.email = request.validated_data['email']
user.save()
# Logout user from all devices
user.auth_token_set.all().delete() # <--- How do I mock this?
return Response(status=status.HTTP_200_OK)
Run Code Online (Sandbox Code Playgroud)
测试视图.py
def test_valid(mocker, user_factory):
user = user_factory.build()
user.id = …Run Code Online (Sandbox Code Playgroud) django pytest python-mock django-rest-framework pytest-django
我有以下(简化的)FBV:
def check_existing_contacts(request):
if request.is_ajax and request.method == "GET":
print('Function called')
return mailgun_validate_email(request)
return JsonResponse({"error": "Incorrect AJAX / GET request."}, status=400)
Run Code Online (Sandbox Code Playgroud)
我想测试该mailgun_validate_email函数是否被调用:
class TestCheckExistingContacts(TestCase):
@patch('myapp.mailgun_validate_email')
def test_new_contact(self, mock):
client = Client()
client.get('/check/', HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertTrue(mock.called)
Run Code Online (Sandbox Code Playgroud)
我确信测试调用如控制台中显示的mailgun_validate_email那样。print('Function called')但是我收到一个断言错误,该错误mock.called是False.
我哪里出错了/我该如何调试?
************更新*******************
当在与视图相同的模块中修补函数时,出现以下错误:
class TestCheckExistingContacts(TestCase):
@patch('[path to views.py with check_existing_contacts].mailgun_validate_email')
def test_new_contact(self, mock):
client = Client()
client.get('/check/', HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertTrue(mock.called)
Run Code Online (Sandbox Code Playgroud)
结果是:
Failure
Traceback (most recent call last):
File "\tests\test_utils.py", line 123, in test_new_contact …Run Code Online (Sandbox Code Playgroud) 我正在尝试确定Python mock.patch(unittest.mock.patch在Py3中)上下文管理器是否会改变全局状态,即它是否是线程安全的.
例如:让我们假设一个线程bar在函数内foo使用上下文管理器修补函数,然后在上下文管理器中,解释器暂停该线程(因为GIL等)并恢复另一个foo在所述上下文管理器之外运行的线程.如果patch是线程安全的我期望的功能的全局状态foo和bar未修改,所以第二个线程将获得的正常行为foo.但是如果patch修改全局状态,第二个线程将获得修改后的行为,foo即使它不在上下文管理器中.
我提到了源代码,但仅通过查看它就无法清楚地说出来.
python-mock ×10
python ×8
mocking ×5
unit-testing ×5
django ×4
datetime ×1
global-state ×1
pytest ×1