繁体   English   中英

具有复杂 __init__ 的类的单元测试

[英]Unit test for classes with complex __init__

我有一个 class 有几种方法,我想为它们编写单元测试。 我面临的问题是这个 class 有一个查询数据库的__init__方法,想象一下这样的:

class MyClass:

    accepted_values = ['a', 'b', 'c']
    
    def __init__(self, database_name):
        self.database = database_name
        self.data = self.query_database()

    def query_database(self):
        data = query_this_database(self.database)
        # clean data
        return data

    def check_values_in_db(self, column_name):
        column = data.column_name
        
        if any(item not in self.accepted_values for item in column):
            print('Oh noes!')
        else:
            print('All good')
    

现在,鉴于此,我想使用一些模拟数据对最后一种方法进行单元测试,但我不能,因为如果我初始化 class,它将需要查询数据库。 由于要实际进行查询,需要一个 API 密钥、权限等,这使情况变得更加复杂,这正是我在单元测试期间要避免的。

我对 OOP 和一般的单元测试相对较新,所以我什至不确定我是否正确地构建了 class:也许方法query_database()应该只在稍后阶段而不是在__init__中调用?

编辑:

被要求添加一些细节,所以这里是:

此 class 属于按计划运行的 AWS lambda function。 每小时,此 class 查询最后一小时的数据库,并根据一些预定义的值检查特定列。

如果列中的任何值不属于这些预定义值,它会发送警报 email。 我想测试这个特定的功能,但不必查询数据库,而只需使用模拟值。

我相应地编辑了代码以反映我的意思。

您可以使用unittest.mock来做这种事情。

一种更丑陋的方法是在模拟 class 中覆盖类的init方法,例如:

class MyMockedClass(MyClass):
    def __init__(self):
        self.database = not_a_real_database()
        self.data = not_real_data()

然后在您的测试中使用这个新的 class。

对于您的最后一个问题,这取决于您可能使用的项目结构和框架。 您应该向codereview咨询有关您的项目结构的建议。

您仍然可以在不创建实例的情况下调用 class 方法,但是如果您尝试调用在__init__中定义的属性,则会遇到问题。

您可能还想考虑在__init__之外创建一个空白变量数据,然后在主代码中调用classinstance.data = classinstance.query_database()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM