标签: python-mock

单元测试模拟 GCS

我很难找到一种方法来对此类中存在的read和方法进行单元测试。write我正在尝试使用模拟补丁库创建一个模拟,以避免调用 Google Storage,但我很难弄清楚如何做到这一点。

from google.cloud import storage


class GCSObject(str):
    

    def __init__(self, uri=""):
        self.base, self.bucket, self.path = self.parse_uri(uri)


    def parse_uri(self, uri):
        uri = uri.lstrip("gs://").replace("//", "/").split("/", 1)
        if len(uri) > 1:
            return ("gs://", uri[0], uri[1])
        else:
            return ("gs://", uri[0], "")

    def read(self) -> bytes:
        storage_client = storage.Client()
        bucket = storage_client.bucket(self.bucket)
        return bucket.blob(self.path).download_as_string()

    def write(self, content: bytes):
        storage_client = storage.Client()
        bucket = storage_client.get_bucket(self.bucket)
        blob = bucket.blob(self.path)
        blob.upload_from_string(content)
Run Code Online (Sandbox Code Playgroud)

我目前正在尝试做的事情

@mock.patch("packages.pyGCP.pyGCP.gcs.storage.Client")
def test_upload(client):
    gcs_path = GCSObject("fake_path")
    reader = gcs_path.read()  
    #  confused …
Run Code Online (Sandbox Code Playgroud)

python testing unit-testing python-mock google-cloud-storage

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

如何模拟Django模型查询

我想嘲笑以下CanonPerson模型

def compute(self, is_send_emails, test_email_address):
        cpses = CanonPerson.objects.filter(persons__vpd=6,
                                           persons__country="United States",
                                           persons__role__icontains=';IX;').prefetch_related("persons").using("global")

        for cp in cpses:
           ...
Run Code Online (Sandbox Code Playgroud)

我很CanonPerson.objects.filter遗憾如何模仿以返回一个可交换的集合,以便我可以继续.

这是我到目前为止所做的:

def test_X_count(self):
    with mock.patch('apps.dbank.models.CanonPerson.objects.filter') as canon_patch:
        mock_cp = mock.MagicMock(spec=CanonPerson)
        mock_person = mock.MagicMock(spec=Person)
        mock_person.vpd = 6
        mock_cp.country = "United States"
        mock_cp.role = ";IX;"
        mock_cp.persons.add(mock_person)
        canon_patch.objects.filter.return_value = [mock_cp] // ???
        oi = OptinInvites()
        oi.compute(False, None)
        oi.get_most_recent_email.assert_called_once_with(1)
Run Code Online (Sandbox Code Playgroud)

在计算功能中,我可以看到cpses是MagicMock类型.然而,它不可迭代,for loop之后,只是跳过它.我想通过设置返回值,[mock_cp]我会创建一个可迭代列表?

python django unit-testing python-mock

4
推荐指数
1
解决办法
2525
查看次数

Python模拟补丁实例方法和检查调用参数

我在Python 2.7中使用Mock(http://mock.readthedocs.org/en/latest/)库.我有一个main函数调用我试图测试的一些其他函数.

它调用的其他函数是其他实例方法(例如,def _other_function(self, a, b).

我正在调用我的main函数,我还有其他函数,它调用了补丁.我刚刚添加autospec=True到补丁中.但是当我检查调用参数时,它会显示一个self参数(如预期的那样):

python2.7> _other_function_mock.call_args_list
[call(<some.module.class.method object at 0x9acab90>, 1, 2)]
Run Code Online (Sandbox Code Playgroud)

在设置之前autospec=True,它只会显示我实际传递的参数(1和2).从现在调用args显示引用self,我不能只调用mock_object.assert_any_call(1, 2).我需要从中挑选出来mock_object.call_args_list并进行比较.

有没有办法仍然调用,mock.assert_any_call而不必手动选择参数来检查传递的参数是否正确?

或者,我是否可以采取更好的方法来修补实例方法?

python unit-testing mocking python-mock

4
推荐指数
1
解决办法
5693
查看次数

Python请求Mock不会捕获超时异常

我写了一个unittest来测试请求包的超时

my_module.py:

import requests

class MyException(Exception): pass

def my_method():
    try:
        r = requests.get(...)
    except requests.exceptions.Timeout:
        raise MyException()
Run Code Online (Sandbox Code Playgroud)

单元测试:

from mock import patch
from unittest import TestCase
from requests.exceptions import Timeout

from my_module import MyException

@patch('my_module.requests')
class MyUnitTest(TestCase):
    def my_test(self, requests):
        def get(*args, **kwargs):
            raise Timeout()

        requests.get = get

        try:
            my_module.my_method(...)
        except MyException:
            return

        self.fail("No Timeout)
Run Code Online (Sandbox Code Playgroud)

但是当它运行时,try块my_method永远不会捕获requests.exceptions.Timeout

python python-mock python-requests

4
推荐指数
1
解决办法
1926
查看次数

Python测试:将假文件与模拟&io.StringIO一起使用

我正在尝试测试可在文件上运行的某些代码,但似乎无法理解如何使用替换实际文件,mockio.StringIO 我的代码几乎是以下内容:

class CheckConfig(object):
    def __init__(self, config):
        self.config = self._check_input_data(config)

    def _check_input_data(self, data):
        if isinstance(data, list):
            return self._parse(data)
        elif os.path.isfile(data):
            with open(data) as f:
                return self._parse(f.readlines())

    def _parse(self, data):
        return data
Run Code Online (Sandbox Code Playgroud)

我有一个可以接受列表或文件的类,如果它是一个文件,则将其打开并将其提取到列表中,然后对结果列表执行所需的操作。

我的工作测试如下:

def test_CheckConfig_with_file():
    config = 'config.txt'
    expected = parsed_file_data
    actual = CheckConfig(config).config
    assert expected == actual
Run Code Online (Sandbox Code Playgroud)

我想替换对文件系统的调用。我试过用替换文件,io.StringIO但从中得到一个TypeErroros.path.isfile()因为它期望是字符串,字节或整数。我也尝试isfile像这样模拟方法:

@mock.patch('mymodule.os.path')
def test_CheckConfig_with_file(mock_path):
    mock_path.isfile.return_value = True
    config = io.StringIO('data')
    expected = parsed_file_data
    actual = CheckConfig(config).config
    assert expected == actual
Run Code Online (Sandbox Code Playgroud)

但是我仍然得到与导致异常 …

python unit-testing mocking python-mock

4
推荐指数
1
解决办法
4444
查看次数

如何在 Python 中模拟用户输入

我目前正在尝试学习如何使用 Python 进行单元测试,并了解了 Mocking 的概念,我是一名初学者 Python 开发人员,希望在发展 Python 技能的同时学习 TDD 的概念。我正在努力学习使用Python unittest.mock 文档的用户给定输入来模拟类的概念。如果我能得到一个如何模拟某个函数的例子,我将非常感激。我将使用此处找到的示例:示例问题

class AgeCalculator(self):

    def calculate_age(self):
        age = input("What is your age?")
        age = int(age)
        print("Your age is:", age)
        return age

    def calculate_year(self, age)
        current_year = time.strftime("%Y")
        current_year = int(current_year)
        calculated_date = (current_year - age) + 100
        print("You will be 100 in", calculated_date)
        return calculated_date
Run Code Online (Sandbox Code Playgroud)

请有人使用 Mocking 创建一个示例单元测试来自动输入年龄,以便它返回模拟年龄为 100 的年份。

谢谢。

python tdd unit-testing mocking python-mock

4
推荐指数
1
解决办法
5518
查看次数

Python如何重用Mock以避免多次编写mock.patch?

给定的代码如下:

import flask
import time

app = flask.Flask(__name__)

def authorize():
    print('starting authorize io')
    time.sleep(1)
    print('done authorize io')

class BlockingIo():
    def __init__(self, n):
        self.n = n
    def do(self):
        print('starting blocking io')
        time.sleep(1)
        print('ending blocking io')

@app.route('/', methods=['GET'])
@app.route('/<int:n>/', methods=['GET'])
def foo(n=1):
    authorize()
    b = BlockingIo(n)
    b.do()
    return str(n), 200

#app.run(port=5000)
Run Code Online (Sandbox Code Playgroud)

我希望能够为 编写几个测试GET /n/,每个测试都模拟authorizeBlockingIO(n)

app.testing = True
testapp = app.test_client()

import unittest
from unittest import mock

mock.patch('__main__.authorize')

class TestBlockingIo(unittest.TestCase):
    @mock.patch('__main__.authorize')
    @mock.patch('__main__.BlockingIo.do')
    def test_1(self, m, m2):
        r …
Run Code Online (Sandbox Code Playgroud)

python mocking flask python-3.x python-mock

4
推荐指数
1
解决办法
1707
查看次数

如何使用Mock库修补Python类

我在修补课程时遇到了麻烦.我正在尝试修补属于Scrapy的东西 - 一个HtmlXpathSelector类.

这是一些代码:

from scrapy.selector import HtmlXPathSelector
from mock import MagicMock, patch

with patch('scrapy.selector.HtmlXPathSelector') as MockHtml:
    instance = MockHtml.return_value
    instance.method.return_value = 'foo'
    example = HtmlXPathSelector()
    print type(example)
    assert example is instance
    assert example.method == 'foo'
Run Code Online (Sandbox Code Playgroud)

结果是:

<class 'scrapy.selector.lxmlsel.HtmlXPathSelector'>
Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
AssertionError
>>>
Run Code Online (Sandbox Code Playgroud)

这个例子和Mock库教程中的例子差不多.知道为什么它不起作用吗?

python unit-testing mocking scrapy python-mock

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

仅具有特定参数的Python模拟函数

我是Python的新手,并且仅在传递特定参数时才尝试模拟函数。如果传递了所需参数以外的其他参数,我想调用原始函数。

在Python 2.7中,我尝试了如下操作:

from foo import config

def test_something(self):
    original_config = config # config is a Module.

    def side_effect(key):
        if key == 'expected_argument':
            return mocked_result
        else:
            return original_config.get(key)

        config.get = Mock(side_effect=side_effect)

        # actualy_test_something...
Run Code Online (Sandbox Code Playgroud)

它不会工作,因为original_config不是的副本config。它引用了以无限循环结尾的同一模块。我可以尝试克隆原始config模块,但这似乎是过分的。

我可以使用类似于RSpec的模拟吗?例如:

obj.stub(:message).with('an_expected_argument').and_return('a_mocked_result')

任何帮助,将不胜感激。谢谢。

python python-2.7 python-mock

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

在芹菜任务中嘲笑一个电话

我有一个运行芹菜任务的烧瓶应用程序.我正在尝试模拟在该任务中发生的单个API调用.

views.py

from mypackage.task_module import my_task
@app.route('/run_task')
def run_task():
    task = my_task.delay()
    return some_response
Run Code Online (Sandbox Code Playgroud)

task_module.py

from mypackage.some_module import SomeClass

@celery.task
def my_task():
    return SomeClass().some_function()
Run Code Online (Sandbox Code Playgroud)

some_module.py

from mypackage.xyz import external_service
class SomeClass(object):
    def some_function(self):
        #do some stuff
        result = external_service(some_param)
        if 'x' in result:
             #do something
        elif 'y' in result:
             #do something else
Run Code Online (Sandbox Code Playgroud)

我想模拟该result = external_service()行,以便我可以触发第一个或第二个代码路径.

所以这就是我正在尝试的:

@mock.patch('mypackage.some_module.external_service', autospec=True)
def test_x_path(my_mock):
    my_mock.return_value = {'x': some_val}
    #run test, expect 'x' code path to run
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,因为(我认为)补丁发生在Flask的Python过程中,而不是Celery正在使用的补丁.嘲讽任务本身并不像我想的测试工作是多么的任务时的行为外部服务回报'x''y' …

unit-testing celery flask python-mock

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