【发布时间】:2012-04-16 09:08:34
【问题描述】:
我刚刚开始使用 Python 的 mock 库来帮助编写更简洁和独立的单元测试。我的情况是我有一个类可以从非常多毛的格式中读取数据,我想在这个类上测试一个方法,它以干净的形式呈现数据 格式。
class holds_data(object):
def __init__(self, path):
"""Pulls complicated data from a file, given by 'path'.
Stores it in a dictionary.
"""
self.data = {}
with open(path) as f:
self.data.update(_parse(f))
def _parse(self, file):
# Some hairy parsing code here
pass
def x_coords(self):
"""The x coordinates from one part of the data
"""
return [point[0] for point in self.data['points']]
上面的代码是我所拥有的代码的简化。实际上_parse 是一种相当重要的方法,我在功能级别上对其进行了测试。
不过,我希望能够在单元测试级别测试x_coords。如果我通过给它一个路径来实例化这个类,它会违反rules of unit tests,因为:
如果满足以下条件,则测试不是单元测试:
- 它涉及文件系统
所以,我希望能够为holds_data 修补__init__ 方法,然后只需填写x_coords 所需的self.data 部分。比如:
from mock import patch
with patch('__main__.holds_data.__init__') as init_mock:
init_mock.return_value = None
instance = holds_data()
instance.data = {'points':[(1,1),(2,2),(3,4)]}
assert(instance.x_coords == [1,2,3])
上面的代码可以工作,但感觉它是以一种相当迂回的方式进行这个测试。有没有更惯用的方法来修补构造函数,或者这是正确的方法?另外,在我的课堂或测试中是否有一些我遗漏的代码气味?
编辑:需要明确的是,我的问题是在初始化过程中,我的类进行了大量的数据处理来组织将由x_coords 之类的方法呈现的数据。我想知道修补所有这些步骤的最简单方法是什么,而无需提供完整的输入示例。我只想在我控制它使用的数据的情况下测试x_coords 的行为。
我这里是否有代码异味的问题归结为这个问题:
如果我将x_coords 重构为一个以holds_data 作为参数的独立函数,我相信这会更容易。如果“更容易测试 == 更好的设计”成立,这将是要走的路。但是,它需要x_coords 函数来更多地了解holds_data 的内部结构,而我通常会对此感到满意。我应该在哪里进行权衡?更简洁的代码还是更简洁的测试?
【问题讨论】:
标签: python unit-testing mocking