标签: python-mock

如何在类中的方法中模拟外部函数

我需要一些模拟方面的帮助。

我在 mymodule.py 中有以下代码:

from someModule import external_function

class Class1(SomeBaseClass):
    def method1(self, arg1, arg2):
        external_function(param)
Run Code Online (Sandbox Code Playgroud)

现在我有测试代码:

import mock
from django.test import TestCase

from mymodule import class1
class Class1Test(TestCase) 
    def test_method1:
        '''how can I mock external_function here?'''
Run Code Online (Sandbox Code Playgroud)

python unit-testing mocking python-mock

5
推荐指数
1
解决办法
2171
查看次数

模拟修补类方法不起作用

我将 Django 与 DRF 和 python 模拟一起使用。我想做的是测试我的视图并模拟序列化器和一些方法。

这就是我所拥有的:

views.py

from gmm_mobile.v1.serializers import RegisterParticipationSerializer
from gmm_mobile.v1.exceptions import GameOrCampaignDoesNotExist
from gmm_util.header import Header
from gmm_util.response import ResponseUtils
from gmm_util.permissions import MobileTokenPermission
from gmm_util.permissions import MobileTokenAuthentication

class ParticipantViewMobile(APIView):
    permission_classes = (MobileTokenPermission, )
    authentication_classes = (MobileTokenAuthentication, )

    def post(self, request, service_id, campaign_id):
        try:
            environment_info = Header.get_environment_info(request)

            request.data[Field.GAME_SERVICE_ID] = service_id
            request.data[Field.CAMPAIGN] = campaign_id
            request.data[Field.LOCATION] = environment_info

            participation_serializer = RegisterParticipationSerializer(data=request.data)
            participation_serializer.is_valid(raise_exception=True)
            participation_serializer.save()

            return ResponseUtils.created()
        except Http404:
            raise GameOrCampaignDoesNotExist()
Run Code Online (Sandbox Code Playgroud)

serializers.py

from gmm_mobile.v1.serializers import RegisterParticipationSerializer
from gmm_mobile.v1.exceptions import …
Run Code Online (Sandbox Code Playgroud)

python django django-unittest python-mock django-rest-framework

5
推荐指数
1
解决办法
1266
查看次数

将mock.patch的autospec选项与自定义Mock子类一起使用

我正在尝试使用(反向移植)模块将间谍附加到类中的方法mock。也就是说,我想创建一个模拟,其工作原理与原始方法类似,但提供常用Mock功能call_count,例如等。

这是我当前使用的代码:

import mock

class MyClass(object):
    def my_method(self, arg):
        return arg + 1

def unit_under_test():
    inst = MyClass()
    return inst.my_method(1)

with mock.patch.object(MyClass, 'my_method', autospec=True,
                       side_effect=MyClass.my_method) as spy:
    result = unit_under_test()
    assert result == 2
    assert spy.call_count == 1
Run Code Online (Sandbox Code Playgroud)

效果很好。现在我想使用 的自定义子类MagicMock来代替。文档说这可以通过参数patchnew_callable完成。但是,new_callableautospec不能一起使用:

class MyMock(mock.MagicMock):
    pass

with mock.patch.object(MyClass, 'my_method', autospec=True,
                       side_effect=MyClass.my_method,
                       new_callable=MyMock) as spy:
    ...
Run Code Online (Sandbox Code Playgroud)
Traceback (most recent call last):
  File "./mocktest.py", line 19, in <module>
    new_callable=MyMock) …
Run Code Online (Sandbox Code Playgroud)

python python-2.7 python-mock

5
推荐指数
1
解决办法
548
查看次数

如何将 mock_open 与 Python UnitTest 装饰器一起使用?

我有一个测试如下:

import mock

# other test code, test suite class declaration here

@mock.patch("other_file.another_method")
@mock.patch("other_file.open", new=mock.mock_open(read=["First line", "Second line"])
def test_file_open_and_read(self, mock_open_method, mock_another_method):
    self.assertTrue(True) # Various assertions.
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

类型错误:test_file_open_and_read() 需要 3 个参数(给出 2 个)

我试图指定我想要__builtin__.open模拟另一个文件的方法,mock.mock_open而不是装饰器mock.MagicMock的默认行为patch。我怎样才能做到这一点?

python unit-testing mocking python-mock python-unittest

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

如何从 python 的`mock.assert_Called_with()` 中获取差异?

当调用unittest.TestCase.assertEqual()两个复杂的字典时,我得到了一个很好的差异。

有什么办法可以从 Python 2.7 中获得差异mock.Mock.assert_called_with吗?我正在测试使用一些具有复杂值的 dict 参数的调用,当其中一个只是缺少一个布尔值时,很难看出问题是什么。

例如

AssertionError: Expected call: post('http://cloud-atlas.cogolo.net/api/executions', auth=('cloudatlas', 'cloudatlas'), data={'environment': 'hadoop', 'source': 'repo', 'output_path': 'hdfs://namenode-01/user/erose/testing', 'production': True, 'input_path': 'hdfs://namenode-01/foo/bar', 'name': 'linecount', 'mrcloud_options': '{"mrcloud_option_A": "foobar", "hadoop_user_name": "erose"}', 'details': '{"path_to_file": "linecount.py", "parameters": {}, "branch": "master", "repo_name": "example_repo"}'}, headers={'X-COGO-CLOUDATLAS-USER': 'erose'})
Actual call: post('http://cloud-atlas.cogolo.net/api/executions', auth=('cloudatlas', 'cloudatlas'), data={'input_path': 'hdfs://namenode-01/foo/bar', 'name': 'linecount', 'environment': 'hadoop', 'source': 'repo', 'output_path': 'hdfs://namenode-01/user/erose/testing', 'details': '{"path_to_file": "linecount.py", "parameters": {}, "branch": "master", "repo_name": "example_repo"}', 'mrcloud_options': '{"mrcloud_option_A": "foobar", "hadoop_user_name": "erose"}'}, headers={'X-COGO-CLOUDATLAS-USER': 'erose'})
Run Code Online (Sandbox Code Playgroud)

python python-2.7 python-mock python-unittest

5
推荐指数
1
解决办法
469
查看次数

在模块中导入之前模拟库

我有 python 文件

\n\n
$ tree .\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 my_module.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 setup.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 test_my_module.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tox.ini\n\n1 directory, 5 files\n
Run Code Online (Sandbox Code Playgroud)\n\n

my_module.py

\n\n
$ cat app/my_module.py\nfrom pymongo import MongoClient\n\nclient = MongoClient(\'mongodb://localhost:27017/\')\n\npost = client.test_database.posts.find_one()\n\ndef ret_value():\n    return db.posts\n
Run Code Online (Sandbox Code Playgroud)\n\n

毒物文件

\n\n
$ cat tox.ini\n[tox]\nenvlist = py35\n\n[testenv]\ndeps=\n    coverage>=4.1\n    flake8\n    pylint\n    pytest-cov==2.2.1\n    pytest==3.0.7\n    pytest-mock\n    pytest-xdist\n        pymongo\n        mock\ncommands=py.test -n 5 -l\nsetenv =\n    XYZ = 123\n
Run Code Online (Sandbox Code Playgroud)\n\n

测试我的模块.py

\n\n
$ cat test_my_module.py\nimport os\n\nimport mock\n\nwith mock.patch(\'app.my_module.MongoClient\'):\n    from app import my_module\n\ndef test_my_module_method():\n    assert os.getenv(\'XYZ\') == \'123\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 中my_module.py …

python unit-testing mocking python-mock

5
推荐指数
0
解决办法
511
查看次数

可以在不模拟对象的其他属性的情况下模拟 python 构造函数吗?

是否可以在继续使用同名其他字段/函数的生产版本的同时模拟 python 构造函数?例如,给定生产代码:

class MyClass:
    class SubClass:
        def __init__(self) -> None:
            print("\nreal sub init called")

        class SubSubClass:
            def __init__(self) -> None:
                print("\nreal sub sub init called")
Run Code Online (Sandbox Code Playgroud)

以及以下测试代码:

class FakeSubClass:
    def __init__(self) -> None:
        print("\nfake init called")


def test():
    MyClass.SubClass()
    MyClass.SubClass.SubSubClass()

    MyClass.SubClass = Mock(side_effect=FakeSubClass)

    MyClass.SubClass()
    MyClass.SubClass.SubSubClass()
Run Code Online (Sandbox Code Playgroud)

我们得到以下输出:

real sub init called

real sub sub init called

fake init called
Run Code Online (Sandbox Code Playgroud)

请注意,最后一行MyClass.SubClass.SubSubClass()没有创建真正的 SubSubClass,因为此时它是 SubClass 模拟的自动创建的属性。

我想要的输出如下:

real sub init called

real sub sub init called

fake init called

real sub sub …
Run Code Online (Sandbox Code Playgroud)

python unit-testing mocking python-mock

5
推荐指数
1
解决办法
2947
查看次数

模拟位于 __init__.py 中的方法

我想模拟init .py 中的一个方法,但实际上它不起作用。

有一个示例来演示该问题以及我如何尝试编写单元测试:

被测代码:src.main.myfile:

from src.main.utils import a_plus_b

def method_under_test():
    a_plus_b()
Run Code Online (Sandbox Code Playgroud)

a_plus_b位于src.main.utils模块中的__init__.py中:

def a_plus_b():
    print("a + b")
Run Code Online (Sandbox Code Playgroud)

单元测试:

import src.main.utils
import unittest
from mock import patch
from src.main.myfile import method_under_test

class my_Test(unittest.TestCase):
    def a_plus_b_side_effect():
       print("a_plus_b_side_effect")

    @patch.object(utils, 'a_plus_b')
    def test(self, mock_a_plus_b):
        mock_a_plus_b.side_effect = self.a_plus_b_side_effect
        method_under_test()
Run Code Online (Sandbox Code Playgroud)

单元测试打印“a + b”,而不是副作用。谁能帮我解决我做错了什么?

python unit-testing python-mock python-unittest

5
推荐指数
1
解决办法
3747
查看次数

如何模拟对象方法返回值

我目前拥有的是:

def some_method():
    some_obj = some_other_method()
    # This is what I want to mock return value of:
    some_obj.some_obj_some_method()

@patch('some_package.some_other_method')
def test_some_stuff(some_other_method_patch):
    some_other_method_patch.return_value = SomeObject()
Run Code Online (Sandbox Code Playgroud)

我怎样才能将 some_obj.some_obj_some_method() 返回值设置为 False?

python unit-testing mocking pytest python-mock

5
推荐指数
1
解决办法
5670
查看次数

如何在 Python 的 unittest.mock 中正确使用模拟 call_args?

考虑以下文件:

圣手手榴弹.py

def count(one, two, five='three'):
    print('boom')
Run Code Online (Sandbox Code Playgroud)

test_holy_hand_grenade.py

from unittest import mock
import holy_hand_grenade

def test_hand_grenade():
    mock_count = mock.patch("holy_hand_grenade.count", autospec=True)
    with mock_count as fake_count:
        fake_count(1, 2, five=5)

        # According to https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.call_args
        # this should work
        assert fake_count.call_args.kwargs['five'] == 5
Run Code Online (Sandbox Code Playgroud)

根据文档,call_args应该是:

这要么是 None (如果尚未调用模拟),要么是最后一次调用模拟的参数。这将采用元组的形式:第一个成员,也可以通过 args 属性访问,是调用模拟的任何有序参数(或空元组),第二个成员,也可以通过访问kwargs 属性是任何关键字参数(或空字典)。

(强调我的)

但这在我的脸上炸开了锅 TypeError: tuple indices must be integers or slices, not str

嗯。不?

我真的不明白的是,如果这是一个调用对象,它就是,因为

assert isinstance(fake_count.call_args, (mock._Call,))
Run Code Online (Sandbox Code Playgroud)

通过,它应该有 kwargs 和 args。它……嗯,确实如此。但它们似乎实际上并不是正确的:

assert isinstance(fake_count.call_args.kwargs, (mock._Call,))  #this works
assert isinstance(fake_count.call_args.kwargs, (dict,))  # doesn't …
Run Code Online (Sandbox Code Playgroud)

python mocking python-3.x python-mock

5
推荐指数
1
解决办法
2324
查看次数