将模拟对象添加到sqlalchemy集合会引发异常

时间:2014-08-19 10:59:29

标签: python unit-testing sqlalchemy mocking python-mock

我正在为SQLAlchemy模型类编写一个单元测试,它具有一对多关系,但无法将模拟对象添加到集合中。

受测试的课程:

class PCLRun(Base):
    __tablename__ = 'pcl_runs'
    id = Column(Integer, primary_key=True)
    ...
    files = relationship("PCLOutputFile", backref='pcl_run')

class PCLOutputFile(Base):
    __tablename__ = 'pcl_output_files'
    id = Column(Integer, primary_key=True)
    ...
    pcl_run_id = Column(Integer, ForeignKey('pcl_runs.id'))

测试代码:

class PCLRunTests(unittest.TestCase):
    def test_foo(self):
        file_mock = mock.Mock()
        pcl_run = PCLRun()
        pcl_run.files.append(file_mock)
        ...

追加模拟对象会引发异常:

TypeError: 'Mock' object has no attribute '__getitem__'

有没有办法通过向其中添加模拟来对包含关系的类进行单元测试,同时保持集合的行为类似于简单列表?

我使用模拟1.0.1和sqlalchemy 0.8.2。

1 个答案:

答案 0 :(得分:0)

我认为问题在于PCLRun实例期望PCLOutputFile类的实例作为append方法的参数。您的Mock实例没有相同的属性,因此在尝试__getitem__方法时会引发错误。

您可以尝试利用Python使用duck-typing创建一个Mock对象,其中包含PCLOutputFile文件的所有属性,但这可能会很难,具体取决于列之外的继承元数据的数量值查询需要..

或者,您可以定义setup / teardown方法/ fixture,它们会在您的测试表中创建PCLOutputFile类的 real 实例。 nosetest模块为这种类型的测试模式提供tools