【问题标题】:Mocking a class attribute模拟类属性
【发布时间】:2021-09-23 15:33:32
【问题描述】:

我有一个要模拟的具有单个类属性的类

my_class.py

class MyClass:

    __attribute = ['123', '456']

test_my_class.py

import pytest
from directory.my_class import MyClass

def test_1(mocker):
    with mocker.patch.object(MyClass, '__attribute', {'something': 'new'}):
        test = MyClass()

我明白了:

E           AttributeError: <class 'directory.my_class.MyClass'> does not have the attribute '__attribute'

我在尝试时也遇到了同样的错误:

def test_2(mocker):
    with mocker.patch('directory.my_class.MyClass.__attribute', new_callable=mocker.PropertyMock) as a:
        a.return_value = {'something': 'new'}
        test = MyClass()

我还尝试了直接分配以及这篇文章中的其他建议: Better way to mock class attribute in python unit test

我的项目正在使用来自此插件的模拟装置:https://pypi.org/project/pytest-mock/

【问题讨论】:

  • __attribute 受名称修改的影响;我会避免使用__-prefixed 名称,直到您找到使用它的理由。如果你想建议它是类私有的,_attribute 就足够了。
  • IMO 我会避免使用双下划线类属性。 mangling 这个名字比它的价值更令人头疼。此外,如果一个变量是私有的,那么理想情况下测试不应该访问它。使其成为可默认的 ctor 参数,这样您就可以在测试中放置适当的值而无需修补。
  • 谢谢 - 将避免双下划线

标签: python class mocking pytest


【解决方案1】:

您可以使用PropertyMock 完成上述操作

from unittest.mock import patch, PropertyMock

class MyClass:
  attr = [1, 2, 3]

with patch.object(MyClass, "attr", new_callable=PropertyMock) as attr_mock:
  attr_mock.return_value = [4, 5, 6]

  print(MyClass.attr) # prints [4, 5, 6]

print(MyClass.attr) # prints [1, 2, 3]

文档参考:https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock

【讨论】:

  • 我得到:“E AttributeError: __enter__”
  • 您可以现场(并且单独)试用:replit.com/@eelkevdbos/HighlevelMistySection#main.py
  • 是的,刚刚试了一下,效果很好……一定是我的环境中的东西 - 谢谢
  • __enter__ 错误提示该类(或其实例)在某处用作上下文管理器。
猜你喜欢
  • 1970-01-01
  • 2020-10-16
  • 2018-09-21
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
相关资源
最近更新 更多