标签: python-mock

我应该如何在Python中使用Mocks进行测试?

我可以看到两种不同的方法将mocks注入到我想要测试的python代码中:

  1. 依赖注入:

    允许协作类传递到被测对象的构造函数中,并传入模拟对象(以及必要时的工厂,如Java)

  2. 猴子补丁:

    使用模拟对象工厂来锁定被测模块中的协作类(以便构建协作类实际上创建了一个模拟对象).我不需要允许它们通过构造函数注入或创建任何工厂.

python 模拟库(例如,moxmock)似乎支持这两种方法.我应该在Python中使用哪种方法,这些是合理的还是有更好的方法?

python tdd unit-testing mocking python-mock

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

模拟Python可迭代用于Sphinx

我正在使用Sphinx来记录依赖于wxPython的项目,使用autodocs扩展,以便它自动生成来自docstrings的页面.该autodocs扩展自动每个模块你在工作import,这是很好的为我们的软件包,但就是一个问题,当我们import一个大的外部库像wxPython的.因此,不是让它从wxPython生成所有内容,而是使用unittest.mock 库模块(以前是外部包Mock).最基本的设置适用于wxPython的大多数部分,但是我遇到了一种我看不到简单方法的情况(可能是因为我本周对模拟的相对不熟悉).

目前,我的conf.py文件结尾有以下内容:

MOCK_MODULES = ['wx.lib.newevent']  # I've skipped irrelevant entries...

for module_name in MOCK_MODULES:
    sys.modules[module_name] = mock.Mock()
Run Code Online (Sandbox Code Playgroud)

对于所有wxPython模块,但是wx.lib.newevent,这非常有效.但是,这里我使用newevent.NewCommandEvent()函数[1]为特定场景创建事件.在这种情况下,我会在NewCommandEvent()通话时收到警告TypeError: 'Mock' object is not iterable.

虽然我可以看到如何使用补丁来处理这个以构建单元测试(我将在下个月进行!),我很难看到如何在我的Sphinx配置中将它集成到一个简单的级别.

编辑:我刚尝试使用MagicMock(); 这仍然会在同一点产生错误,尽管它现在产生了ValueError: need more than 0 values to unpack.这似乎是朝着正确方向迈出的一步,但我仍然不确定如何处理这个模块的明确设置.也许这是最好的解决方案?


脚注

  1. 是的,这是一个函数,命名约定使它看起来像一个类; wxPython遵循整个wxWidgets工具包中使用的C++命名约定.

python mocking python-sphinx python-mock

9
推荐指数
1
解决办法
688
查看次数

如何使用mock.patch模拟生成器

我已经浏览了https://docs.python.org/3/library/unittest.mock-examples.html页面,我看到他们已经列出了如何模拟生成器的示例

我有一个代码,我调用生成器给我一组值,我保存为字典.我想在单元测试中模拟对这个生成器的调用.

我写了以下代码,但它不起作用.

我哪里错了?

In [7]: items = [(1,'a'),(2,'a'),(3,'a')]

In [18]: def f():
    print "here"
    for i in [1,2,3]:
        yield i,'a'

In [8]: def call_f():
   ...:     my_dict = dict(f())
   ...:     print my_dict[1]
   ...: 

In [9]: call_f()
"here"
a

In [10]: import mock


In [18]: def test_call_f():
    with mock.patch('__main__.f') as mock_f:
        mock_f.iter.return_value = items
        call_f()
   ....: 

In [19]: test_call_f()
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-19-33ca65a4f3eb> in <module>()
----> 1 test_call_f()

<ipython-input-18-92ff5f1363c8> in test_call_f()
      2     with mock.patch('__main__.f') as …
Run Code Online (Sandbox Code Playgroud)

python generator nose python-mock python-unittest

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

仅在一个模块中修补方法

例如,我有一些foo.py带有以下代码的 module( ):

import requests

def get_ip():
    return requests.get('http://jsonip.com/').content
Run Code Online (Sandbox Code Playgroud)

bar.py具有类似代码的模块:

import requests

def get_fb():
    return requests.get('https://fb.com/').content
Run Code Online (Sandbox Code Playgroud)

我只是不明白为什么接下来会发生:

from mock import patch

from foo import get_ip
from bar import get_fb

with patch('foo.requests.get'):
    print(get_ip())
    print(get_fb())
Run Code Online (Sandbox Code Playgroud)

他们两个被嘲笑: <MagicMock name='get().content' id='4352254472'> <MagicMock name='get().content' id='4352254472'> 似乎只修补foo.get_ip方法with patch('foo.requests.get'),但事实并非如此。我知道我可能会bar.get_fb超出with范围进行调用,但在某些情况下,我只在上下文管理器中运行一种调用许多其他方法的方法,并且我只想requests在一个模块中进行修补。有什么办法可以解决这个问题吗?不改变模块中的导入

python python-3.x python-mock python-unittest python-unittest.mock

9
推荐指数
1
解决办法
3163
查看次数

如何将参数从 mock.patch 传递给 new_callable?

我有代码和测试文件:

代码.py

class Code:

    def do_something_inside(self, a, b, c):
        return a-b-c

    def do_something(self, b, c):
        self.do_something_inside(30, b, c)
Run Code Online (Sandbox Code Playgroud)

测试文件

import unittest
import unittest.mock as mock
from code import Code

class TestStringMethods(unittest.TestCase):
    def setUp(self):
        self.code = Code()

    def do_something_inside_stub(self, a, b, c):
        return a+b+c

    @mock.patch('code.Code.do_something_inside', new_callable=do_something_inside_stub)
    def test_add(self):
        self.assertEquals(self.code.do_something(10, 5), 45)

if __name__ == '__main__':
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

我想使用 do_something_inside_stub 模拟 do_something_inside 方法,但执行失败:

E
======================================================================
ERROR: test_add (__main__.TestStringMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.6/unittest/mock.py", line 1171, in patched
    arg = patching.__enter__() …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-mock python-unittest python-3.6

9
推荐指数
1
解决办法
4695
查看次数

在python中模拟整个模块

我有一个从PyPI导入模块的应用程序.我想为该应用程序的源代码编写单元测试,但我不想在这些测试中使用PyPI中的模块.
我想完全模拟它(测试机器不会包含那个PyPI模块,所以任何导入都会失败).

目前,每次我尝试加载我想在单元测试中测试的类时,我都会立即收到导入错误.所以我想也许用

try: 
    except ImportError:
Run Code Online (Sandbox Code Playgroud)

并捕获该导入错误,然后使用command_module.run().这看起来非常危险/丑陋,我想知道是否还有另一种方式.

另一个想法是编写一个适配器来包装PyPI模块,但我仍在努力.

如果你知道我可以模拟整个python包,我会非常感激.谢谢.

python unit-testing python-module mocking python-mock

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

如何只模拟类中的方法

试图为我的基于类的函数编写一个测试用例。这是我班级的骨架

class Library(object):
    def get_file(self):
        pass

    def query_fun(self):
        pass

    def get_response(self):
        self.get_file()

        response = self.query_fun()

        # some business logic here
        return response
Run Code Online (Sandbox Code Playgroud)

我需要创建一个测试用例,它可以只模拟 query_fun并完成其余的工作。在下面尝试过,但似乎不是正确的方向:

from unittest import mock, TestCase
from library.library import Library

class TestLibrary(TestCase):
    def setUp(self):
        self.library = Library()

    @mock.patch('library.library.Library')
    def test_get_response(self, MockLibrary):
        mock_response = {
            'text': 'Hi',
            'entities': 'value',
        }
        MockLibrary.query_fun.return_value = mock_response
        response = MockLibrary.get_response()
        self.assertEqual(response, mock_response)
Run Code Online (Sandbox Code Playgroud)

我期待的是设置 mock 并且调用get_response实际上不会调用原始query_fun方法,而是调用 mock query_fun

python methods unit-testing mocking python-mock

8
推荐指数
1
解决办法
1万
查看次数

在python中模拟grpc响应消息

最近,我一直在使用 MagicMock() 在 python 中模拟 gRPC 调用,但我没有成功模拟我得到的 gRPC 响应消息。这是一段Python客户端代码

def senor_read(self, server_end_point)
with grpc.insecure_channel(server_end_point) as grpc_channel:
    grpc_stub = sensorservice_pb2_grpc.getsensorinfostub(grpc_channel)
    sensor_response = yield grpc_stub.getsensorreading(sensorservice_pb2_grpc.request(
                    sensorname=name, account=account))
    if sensor_response.ok:
        print(" Successful sensor reading")
    elf sensor_resonse.error:
        raise Sensor_ErrorReading(why="Not able to read sensor)

    return convert_resoonse_to_dict(sensor_response)
Run Code Online (Sandbox Code Playgroud)

这是我模拟它的方式(还是新手学习模拟框架)

sensorservice_pb2_grpc = MagicMock()
sensorservice_pb2_grpc.getsensorinfostub = MagicMock()
mock_grpc_stub = MagicMock()
mock_grpc_channel = MagicMock()
mock_grpc_channel.grpc.insecure_channel = MagicMock()
mock_grpc_channel.grpc_channel = MagicMock()
mock_grpc_response = MagicMock(mock_grpc_stub.getsensorreading)
type(mock_grpc_response.return_value).error = PropertyMock(return_value=True)
Run Code Online (Sandbox Code Playgroud)

流程是 python 函数 senor_read() 向远程服务器发出 gRPC 请求并获取读数并传回调用者。

此测试的目的是使代码在“eif”情况下执行并捕获异常。1)当我执行测试代码时,如果情况发生并且我看到其他异常被发送给调用者,它不会进入“elf”。我是否在 gRPC 响应模拟中正确设置了状态?

2)我的模拟步骤对于模拟 gRPC 调用是否正确?

3)此外,当我运行时,我无法看到成功时的打印消息,而只能看到失败测试用例的打印消息。另外,实际功能中的打印不打印? …

python unit-testing mocking python-mock grpc-python

8
推荐指数
0
解决办法
4274
查看次数

Python-当`new`参数不是DEFAULT时,为什么模拟补丁装饰器不会将模拟对象传递给测试函数

在 Python 3.6 中,我unittest.mock.patch用来修补这样的函数:

class SampleTest(TestCase):

    @mock.patch('some_module.f')
    def test_f(self, mocked_f):
        f()
        mocked_f.assert_called()

Run Code Online (Sandbox Code Playgroud)

This passes a mock.MagicMock() as mocked_f and everything works fine. However, when I want to use a custom mock object instead of the default mock.MagicMock() using new argument, the patch decorator does not pass the mocked object to the test_f method. Running this code will raise a TypeError:

class SampleTest(TestCase):

    @mock.patch('some_module.f', new=lambda: 8)
    def test_f(self, mocked_f):
        f()
        mocked_f.assert_called()
Run Code Online (Sandbox Code Playgroud)
TypeError: test_f() missing 1 required positional argument: …
Run Code Online (Sandbox Code Playgroud)

python python-mock python-unittest

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

python 模拟 sqlalchemy 连接

我有一个简单的函数,可以连接到数据库并获取一些数据。

db.py

from sqlalchemy import create_engine
from sqlalchemy.pool import NullPool


def _create_engine(app):
    impac_engine = create_engine(
        app['DB'],
        poolclass=NullPool  # this setting enables NOT to use Pooling, preventing from timeout issues.
    )
    return impac_engine


def get_all_pos(app):
    engine = _create_engine(app)
    qry = """SELECT DISTINCT id, name FROM p_t ORDER BY name ASC"""
    try:
        cursor = engine.execute(qry)
        rows = cursor.fetchall()
        return rows
    except Exception as re:
        raise re
Run Code Online (Sandbox Code Playgroud)

我正在尝试通过模拟此连接来编写一些测试用例 -

测试.py

import unittest
from db import get_all_pos
from unittest.mock import patch
from unittest.mock import …
Run Code Online (Sandbox Code Playgroud)

python sqlalchemy mocking python-mock

8
推荐指数
1
解决办法
1万
查看次数