编程语言
首页 > 编程语言> > 在python单元测试中模拟类属性的更好方法

在python单元测试中模拟类属性的更好方法

作者:互联网

我有一个基类,它定义了一个类属性和一些依赖它的子类,例如:

class Base(object):
    assignment = dict(a=1, b=2, c=3)

我想用不同的作业对这个类进行单元测试,例如空字典,单项等.当然,这是非常简化的,不是重构我的类或测试的问题

我得到的(pytest)测试,最终,工作是

from .base import Base

def test_empty(self):
    with mock.patch("base.Base.assignment") as a:
        a.__get__ = mock.Mock(return_value={})
        assert len(Base().assignment.values()) == 0

def test_single(self):
    with mock.patch("base.Base.assignment") as a:
        a.__get__ = mock.Mock(return_value={'a':1})
        assert len(Base().assignment.values()) == 1

这感觉相当复杂和hacky – 我甚至不完全理解为什么它工作(虽然我熟悉描述符). mock会自动将类属性转换为描述符吗?

一种感觉更符合逻辑的解决方案不起作用:

def test_single(self):
    with mock.patch("base.Base") as a:
        a.assignment = mock.PropertyMock(return_value={'a':1})
        assert len(Base().assignment.values()) == 1

要不就

def test_single(self):
    with mock.patch("base.Base") as a:
        a.assignment = {'a':1}
        assert len(Base().assignment.values()) == 1

我尝试过的其他变种也不起作用(测试中的作业保持不变).

模拟类属性的正确方法是什么?有没有比上面更好/更容易理解的方式?

解决方法:

base.Base.assignment简单地替换为Mock对象.您通过添加__get__方法使其成为描述符.

它有点冗长,有点不必要;你可以直接设置base.Base.assignment:

def test_empty(self):
    Base.assignment = {}
    assert len(Base().assignment.values()) == 0

当然,使用测试并发时这不太安全.

要使用PropertyMock,我会使用:

with patch('base.Base.assignment', new_callable=PropertyMock) as a:
    a.return_value = {'a': 1}

甚至:

with patch('base.Base.assignment', new_callable=PropertyMock, 
           return_value={'a': 1}):

标签:python-mock,python,unit-testing,mocking
来源: https://codeday.me/bug/20191004/1851849.html