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

伊沃·范德维克(Ivo van der Wijk):

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

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

这感觉相当复杂和棘手-我什至还不完全了解它为什么起作用(尽管我对描述符很熟悉)。模拟会自动将类属性转换为描述符吗?

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

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

我尝试过的其他变体也不起作用(测试中的分配保持不变)。

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

马丁·彼得斯(Martijn Pieters):

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}):

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章