【问题标题】:Will unittest work for functional (non-object-oriented) program in Python?单元测试是否适用于 Python 中的功能性(非面向对象)程序?
【发布时间】:2023-03-26 18:24:01
【问题描述】:

我是一名初级程序员,过去一周我一直在尝试编写单元测试。我通读了单元测试文档并观看了两个关于使用Mock 实现单元测试的长教程。文档广泛引用了模拟类,但对于函数,我不确定是否应该使用@patch/with patchpatch.dict{}side_effect 或其他一些选项来模拟函数,特别是函数的参数。

mymodule.py

def regex():
    '''Runs a regex, creates a dict 'data' and then calls scraper(data)'''

def scraper(data):
    '''scrapes a website and then calls a function which submits data to a db'''

我想创建一个将测试数据传递给函数 scraper 的测试。提前谢谢你。

【问题讨论】:

    标签: python unit-testing mocking


    【解决方案1】:

    是的,您还可以使用 mock 对非面向对象的代码进行单元测试。

    请看下面的例子:

    from unittest.mock import MagicMock
    def a():
        return 10
    def b():
        print(a())  
    b()
    a = MagicMock(return_value=3)
    b()
    

    输出是:

    10
    3
    

    在前面的示例中,mock 用于伪造/模拟函数 a(),因此您可以单独测试函数 b(),b() 是您的 SUT,而无需调用 a() 实际实现。这对于更复杂的代码很有用,特别是当函数 a() 依赖于单元测试级别中可能不可用的数据时。

    【讨论】:

      【解决方案2】:

      您没有提供足够的示例来真正提供帮助,但有几点意见:

      • 通常,最好对代码进行结构化以避免在测试中进行模拟;在可能的范围内,每个函数都应该是一段独立的代码,可以单独调用。

      • 没有必要模拟参数;只需将测试值传入即可。

      • 我不确定这段代码的用途:

        bar = {'key': 'value'}     
        
        def foo(bar):
            pass
        

        在外层定义的bar 是与函数定义中用作参数的bar 完全独立的变量。给它们取相同的名字会让人困惑……

      • 可以使用patchpatch.objectreturn_value=... 选项模拟函数;但通常,它建议需要重构代码以减少两个函数之间的依赖关系。

      【讨论】:

      • 感谢您的回复,我将澄清这个问题,而不是在这里详细说明。
      • 对,所以在测试中你调用:scraper(test_data)不用mock。
      • 好的,我一定有另一个错误,但我会根据需要进行故障排除并留给另一篇文章。谢谢。
      猜你喜欢
      • 1970-01-01
      • 2010-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多