小马ORM-在测试中拆除

时间:2019-08-24 16:57:06

标签: python pytest ponyorm

我正在使用Pony ORM在我正在开发的python包中管理sqlite数据库。

我想用pytest进行测试。

我的软件包提供了一个“代理”对象,该对象用于连接服务器API并检索“事件”。初始化代理后,将小马orm设置并绑定到sqlite db,无论是在内存中(用于测试)还是文件。

    def setup_db(filepath=None):
        if filepath:
            db.bind(provider="sqlite", filename=filepath, create_db=True)
        else:
            db.bind(provider="sqlite", filename=":memory:", create_db=True)
        db.provider.converter_classes.append((Enum, EnumConverter))
        db.generate_mapping(create_tables=True)

事件的状态使用pony orm存储在sqlite数据库中。

我希望创建一个新的代理对象,并为每个测试创建一个干净的数据库,因此我在conftest.py文件中使用了pytest固定装置。

    @pytest.fixture
    def agent():
        agent=Agent(parm1="param1",...)
        return agent

我无法从数据库中正确地“解除绑定”,并且在第二次测试时出现此错误:

pony.orm.core.BindingError: Database object was already bound to SQLite provider

我想要一些关于最佳方法的建议。 谢谢。

3 个答案:

答案 0 :(得分:1)

对于您的情况,我认为您应该为实体创建一些工厂,并为每种设置创建新的数据库对象。

def define_entities(db):
    class Student(db.Entity):
        ...

    class Group(db.Entity):
        ...

所以您可以做类似的事情

def setup_db(filepath=None):
    db = Database()
    if filepath:
        db.bind(provider="sqlite", filename=filepath, create_db=True)
    else:
        db.bind(provider="sqlite", filename=":memory:", create_db=True)
    define_entities(db)
    db.provider.converter_classes.append((Enum, EnumConverter))
    db.generate_mapping(create_tables=True)

答案 1 :(得分:0)

看看Pony代码,似乎应该清除provider实例的Database属性以使其为 fresh ,以便可以再次绑定。

如果您产生Agent而不是从固定装置返回它,则在yield语句之后放置的所有内容都将作为固定装置拆卸代码运行。

答案 2 :(得分:0)

previous answer from zgoda几乎可以使用。除db.provider外,还需要清除db.schema。我的建议是您创建另一个功能:

def unbind_db():
    db.provider = db.schema = None

您的灯具应该是这样的:

@fixture
def database() -> None:
    setup_db()
    ...
    try:
       yield
    finally:
       unbind_db()