在使用unittest模块进行修补时,是否可以为python中的类成员变量分配side_effect?

2024-04-26 20:29:01 发布

您现在位置:Python中文网/ 问答频道 /正文

是否可以修补类实例变量,并强制它在每次引用时返回不同的值?具体地说,我感兴趣的是使用side_effect参数

  • 我知道,当修补一个方法时,可以将一个副作用分配给一个模拟方法。如果您将side_effect设置为一个列表,它将在每次调用该列表时迭代返回不同的值。在
  • 我想对一个类实例变量做同样的事情,但是不能让它工作,我也看不到任何文档来说明这是否可能

示例

from unittest.mock import patch

def run_test():
    myClass = MyClass()
    for i in range(2):
        print(myClass.member_variable)

class MyClass():
    def __init__(self):
        self.member_variable = None

@patch('test_me.MyClass.member_variable',side_effect=[1,2], create=True)
def test_stuff(my_mock):
    run_test()
    assert False

输出

^{pr2}$

期望输出

-------------- Captured stdout call ---------------------------------------------------------------------------------------------------------------------
1
2
  • 更清楚的是,我知道我可以将成员变量包装在一个get_member\uvariable method()中。这不是我的问题。我只想知道你能不能用副作用来修补成员变量。在

Tags: 实例方法runtest列表defmyclassvariable
2条回答

side_effect可以是函数、iterable或异常(https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.side_effect)。我想这就是它不起作用的原因。在

另一种测试方法是:

>>> class Class:
...     member_variable = None
...
>>> with patch('__main__.Class') as MockClass:
...     instance = MockClass.return_value
...     instance.member_variable = 'foo'
...     assert Class() is instance
...     assert Class().member_variable == 'foo'
...

文件如下:https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch

在你所举的例子中,我无法改变我所想的方式,你可能在这个类中有更多的项目,这个想法可以帮助你。在

不是对属性产生副作用的最佳选择,但它在我需要的时候起作用了。在

附言:最后,我把带我来问你问题的代码作为例子。在

示例:

# -*- coding: utf-8 -*-
# !/usr/bin/env python3

import requests

from src.metaclasses.singleton import Singleton
from src.services.logger import new_logger
from src.exceptions.too_many_retries import TooManyRetries
from src.exceptions.unavailable_url import UnavailableURL

LOG = new_logger(__name__)


class PostbackService(metaclass=Singleton):
    def __init__(self):
        self.session = requests.session()

    def make_request(self, method, url, headers, data=None, retry=0):
        r = self.session.request(method, url, data=data, headers=headers)

        if r.status_code != 200:
            if retry < 3:
                return self.make_request(method, url, headers, data, retry + 1)
            message = f"Error performing request for url: {url}"
            LOG.error(message)
            raise TooManyRetries(message)

        return r.json()

测试:

^{pr2}$

如你所见,我通过改变每一个的副作用来重新创建magicmock。它不是漂亮的代码和超级Python,但它如预期的那样工作。 我用@rsarai从unittest文档中发送的链接创建这个magicmock对象。在

相关问题 更多 >