标签: python-mock

模拟打开python中的单元测试

我想使用unittest测试一个使用上下文管理器从文件读取的方法:

with open(k_file, 'r') as content_file:
    content = content_file.read()
Run Code Online (Sandbox Code Playgroud)

我不想在我的系统上创建一个文件,所以我想嘲笑它,但我现在并没有太大的成功.我发现了mock_open,但我真的不明白我应该如何使用它并在我的测试用例中将mock作为content_file提供.这里有这篇文章,但是我不明白在不修改原始代码的情况下如何在测试用例中编写这个.

有人能指出我正确的方向吗?

python unit-testing mocking python-mock

3
推荐指数
1
解决办法
3791
查看次数

如何在 Python 模拟中调用模拟方法

我想创建一个模拟方法来调用被模拟的底层方法。

我正在想象类似以下内容,但我找不到任何关于持有对被模拟对象的引用的模拟对象的文档,我已将其表示[[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)

python unit-testing mocking python-mock

3
推荐指数
1
解决办法
4166
查看次数

使用mock测试目录是否存在

我已经探索模拟和 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 的返回值如何,断言都会失败。有人可以帮我弄清楚我哪里出了问题吗?

unit-testing mocking python-mock

3
推荐指数
1
解决办法
5129
查看次数

Python Mock在一个类中修补多个方法

我试图在一个类中修补多个方法。这是我的简化设置

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)

python python-mock python-unittest

3
推荐指数
3
解决办法
7896
查看次数

Django 立即测试模拟日期时间

我有一个 Django 测试,我需要模拟 datetime.now(),因为它测试的视图使用 datetime.now()

\n\n

我正在使用 Michael Foord 的模拟库,版本 1.0.1。
\n我正在寻找一种不使用其他库(例如 freezegun)的解决方案。

\n\n

大多数例子都是这样的,这个导入 datetime 并覆盖它,但我正在导入 datetime.datetime 并尝试覆盖它,由于某种原因,这不起作用。

\n\n

覆盖日期时间的工作原理:

\n\n
import 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()\n
Run Code Online (Sandbox Code Playgroud)\n\n

但我想导入 datetime.datetime 并执行以下操作:

\n\n
import 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()\n
Run Code Online (Sandbox Code Playgroud)\n\n

这会导致 TypeError: Need a valid target to patch. 您提供了:“日期时间”。

\n\n

模拟库还指出:

\n\n
\n

target 应该是 \xe2\x80\x98package.module.ClassName\xe2\x80\x99 形式的字符串。目标被导入,指定的对象被新对象替换,因此目标必须可以从您调用补丁的环境中导入。

\n …

python django datetime unit-testing python-mock

3
推荐指数
1
解决办法
6286
查看次数

返回作为参数传递的相同值的模拟方法

我如何使用 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">&lt;function dummy_function at 0x10887f730&gt;</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)

python unit-testing mocking python-mock

3
推荐指数
1
解决办法
4317
查看次数

Django 模拟未按预期工作

我正在与 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)

这怎么可能?我究竟做错了什么?

提前致谢

python django mocking django-testing python-mock

3
推荐指数
1
解决办法
1777
查看次数

在 Django 2 中模拟一个 RelatedManager

这个问题与这个问题直接相关,但那个现在似乎已经过时了。

我正在尝试测试视图而无需访问数据库。为此,我需要对RelatedManager用户进行模拟。

我正在使用pytestpytest-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

3
推荐指数
1
解决办法
868
查看次数

如何使用unittest.mock调试修补方法

我有以下(简化的)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.calledFalse.

我哪里出错了/我该如何调试?

************更新*******************

当在与视图相同的模块中修补函数时,出现以下错误:

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 django django-testing python-mock python-unittest

3
推荐指数
1
解决办法
1634
查看次数

python的`unittest.mock.patch`是否会改变全局状态?

我正在尝试确定Python mock.patch(unittest.mock.patch在Py3中)上下文管理器是否会改变全局状态,即它是否是线程安全的.

例如:让我们假设一个线程bar在函数内foo使用上下文管理器修补函数,然后在上下文管理器中,解释器暂停该线程(因为GIL等)并恢复另一个foo在所述上下文管理器之外运行的线程.如果patch是线程安全的我期望的功能的全局状态foobar未修改,所以第二个线程将获得的正常行为foo.但是如果patch修改全局状态,第二个线程将获得修改后的行为,foo即使它不在上下文管理器中.

我提到了源代码,但仅通过查看它就无法清楚地说出来.

python multithreading global-state python-mock

2
推荐指数
2
解决办法
1982
查看次数