【问题标题】:Unit testing in Python: How to get an if-statement to return TRUE to test the lines within the if-statement?Python 中的单元测试:如何让 if 语句返回 TRUE 以测试 if 语句中的行?
【发布时间】:2021-06-10 02:41:04
【问题描述】:

Python 3.7。我正在尝试对以下功能进行单元测试:

    def is_json_clean():
        # function for is_json_clean here, returns bool

    def json_function(blob, raw_bucket, lake_bucket):
        data_string = blob.download_as_bytes()
        data = json.loads(data_string)
        if is_json_clean(data) is True:
            raw_bucket.copy_blob(blob, lake_bucket)

我对模拟补丁还很陌生,可以在这里举个例子!我如何使用 mock.patch 或类似的东西来获取带有 is_json_clean() 函数的 if 语句来返回 True 以便我可以断言调用了 copy_blob 函数?我想我可以制作一个像这样的补丁:

@mock.patch.object(imported_module, "is_json_clean", return_value=True)
def test_json_function(mock):
    # rest of the test function 
    # including assert statement for the copy_blob function 

但是我如何将它插入到我的测试中以断言我的 copy_blob 函数?我知道有很多与单元测试相关的问题,但我还没有找到我的问题的确切答案(就像我说的,我很新)。任何帮助表示赞赏。谢谢!

【问题讨论】:

  • 需要在测试方法中添加上述装饰器补丁,可以参考mock-patch-object-to-change-the-return-value-of-a-method-called中的示例。
  • @KrishnaChaurasia 好的,更正:我确实将此补丁添加到了测试方法中!应该澄清一下。我现在要问的是,我将如何在测试函数本身中引用该补丁以强制 if 语句为 TRUE,然后调用 copy_blob()。
  • 你不需要做任何事情,只需调用要测试的方法,在测试路径中,mocked方法将替换原来的实现。您可以在if 路径中的原始方法中添加print() 语句,并且在执行测试时应该会看到相同的内容。
  • 我明白了!你说的有道理!那么,当我运行测试时,是否有任何理由不会调用函数 copy_blob ?这是我当前的问题。
  • 我不确定那里发生了什么,您可以在if 路径中添加print() 以查看补丁是否按预期工作,然后使用调试器深入挖掘。

标签: python python-3.x unit-testing mocking


【解决方案1】:

您的模拟看起来是正确的,但我没有看到在您的测试用例中传递了 blob、raw_bucket 或 lake_bucket 参数。以下是我将如何编写它,嘲笑所有 3 个参数。

import unittest

from unittest import mock

import imported_module

class MyTest(unittest.TestCase):
    @mock.patch.object(imported_module, "is_json_clean", return_value=True)
    def test_json_function(self, mock_is_json_clean):
        json_blob = '{"mykey": "myvalue"}'
        mock_blob = mock.Mock()
        mock_blob.download_as_bytes.return_value = json_blob
        mock_raw_bucket = mock.Mock()
        mock_lake_bucket = mock.Mock()

        imported_module.json_function(mock_blob, mock_raw_bucket, mock_lake_bucket)

        mock_raw_bucket.copy_blob.assert_called_once_with(mock_blob, mock_lake_bucket)

if __name__ == "__main__":
    unittest.main()

可以看到我传入了一个mock_blob,mock了download_as_bytes的返回值,同时传入了两个bucket。从那里,我可以对mock_raw_bucket.copy_blob 调用进行断言。我能够让这段代码在这里运行和传递:https://replit.com/@WesH1/TautLiveTelephone#main.py

【讨论】:

  • 啊! download_as_bytes 对我来说是关键。谢谢!
  • @idly-and-sambal 太好了,很高兴听到它修复了它。如果答案解决了您的问题,请将其标记为已接受的答案。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-08-16
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
  • 1970-01-01
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多