【问题标题】:Unittesting some function comprising instance of some class with pytest使用 pytest 对包含某些类的实例的某些函数进行单元测试
【发布时间】:2021-10-07 12:48:28
【问题描述】:

考虑具有以下内容的模块some_module.py(在我的实际用例中,SomeClasssome_function 定义在单独的模块中):

class SomeClass:
    def __init__(self, v):
        self.some_attr = v

    def some_method(self):
        self.some_attr += self.some_attr


def some_function(val):
    c = SomeClass(val)
    c.some_method()
    return c

假设我已经使用pytestSomeClass 进行了单元测试。现在我想对some_function 进行单元测试。我的理解是我应该嘲笑与SomeClass 相关的所有内容。我尝试将以下测试功能添加到some_module.py

def test_some_function(mocker):
    # arrange
    c = mocker.MagicMock()
    c.some_attr = 10

    mocker.patch('some_module.SomeClass', return_value=c)
    mocker.patch('some_module.SomeClass.some_method')
    
    # act
    c = some_function(10)

    # assert
    assert c.some_attr == 20

在终端中运行pytest some_module.py(显然)会导致测试失败,因为c.some_attr 是10。测试函数应该是什么样子?

【问题讨论】:

  • “我的理解是我应该模拟与 SomeClass 相关的所有内容。”这是为什么呢?
  • @MisterMiyagi,鉴于 Laurent 的回答,我认为我想到的单元测试的定义是错误的(不是你想到的那个?)。如果这里建议的负担不是太大,您是否支持不嘲笑的做法,例如:softwareengineering.stackexchange.com/a/382092

标签: python-3.x unit-testing oop pytest


【解决方案1】:

在您的示例中,由于SomeClass 已经成功测试,并且some_function 的目的似乎只是返回SomeClass 的实例,而some_method 已被调用一次且仅一次,因此嘲笑它没有意义(如果可能,最好使用avoid mocks)。

因此,我建议你像这样测试some_function

from some_module import SomeClass, some_function


def test_some_function():

    c = some_function(10)
    assert isinstance(c, SomeClass)
    assert c.some_attr == 20

    c = some_function(-10)
    assert isinstance(c, SomeClass)
    assert c.some_attr == -20

    c = some_function(0)
    assert isinstance(c, SomeClass)
    assert c.some_attr == 0

【讨论】:

  • 谢谢@Laurent,我想我需要在脑海中改变单元测试的定义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-25
  • 2016-06-23
  • 1970-01-01
相关资源
最近更新 更多