首页 > 解决方案 > 对没有输入参数的类方法进行 Python 单元测试

问题描述

self给定一个具有仅包含输入的类方法的类:

class ABC():
    def __init__(self, input_dict)
        self.variable_0 = input_dict['variable_0']
        self.variable_1 = input_dict['variable_1']
        self.variable_2 = input_dict['variable_2']
        self.variable_3 = input_dict['variable_3']

    def some_operation_0(self):
        return self.variable_0 + self.variable_1

    def some_operation_1(self):
        return self.variable_2 + self.variable_3

第一个问题:这是非常糟糕的做法吗?我应该重构some_operation_0(self)以明确地获取必要的输入some_operation_0(self, variable_0, variable_1)吗?如果是这样,测试非常简单。

第二个问题:在该方法上设置我的单元测试的正确方法是some_operation_0(self)什么?我应该设置一个我初始化的夹具input_dict,然后用一个模拟对象实例化这个类吗?

@pytest.fixture
def generator_inputs():
    f = open('inputs.txt', 'r')
    input_dict = eval(f.read())
    f.close()
    mock_obj = ABC(input_dict)

def test_some_operation_0():
    assert mock_obj.some_operation_0() == some_value

(我是 python 和一般单元测试的新手......)

标签: pythonunit-testingpytest

解决方案


这些方法确实需要一个参数:self. 没有必要嘲笑任何东西。相反,您可以简单地创建一个实例,并验证方法在调用时是否返回预期值。

对于您的示例:

def test_abc():    
    a = ABC({'variable_0':0, 'variable_1':1, 'variable_2':2, 'variable_3':3))
    assert a.some_operation_0() == 1
    assert a.some_operation_1() == 5

如果构造一个实例非常困难,您可能需要更改您的代码,以便可以从标准的内存数据结构(例如字典)中实例化该类。在这种情况下,您可以创建一个单独的函数来读取/解析文件中的数据并使用“基于数据结构”的__init__方法,例如make_abc()或类方法。

如果这种方法不能推广到您的实际问题,您可以想象提供对ABC 识别或关心的键名或其他元数据的编程访问。然后,您可以以编程方式构造一个“默认”实例,例如输入字典中的每个值都是默认构造值的实例(例如0for int):

class ABC():
    PROPERTY_NAMES = ['variable_0', 'variable_1', 'variable_2', 'variable_3']

    def __init__(self, input_dict):
        # implementation omitted for brevity
        pass

    def some_operation_0(self):
        return self.variable_0 + self.variable_1

    def some_operation_1(self):
        return self.variable_2 + self.variable_3

def test_abc():
    a = ABC({name: 0 for name in ABC.PROPERTY_NAMES})
    assert a.some_operation_0() == 0
    assert a.some_operation_1() == 0

推荐阅读