简体   繁体   English

Python 单元测试:模拟外部库 function 从 class ZA8CFDE6331BD1C49EB2AC96F8691 调用

[英]Python unittest: Mock an external library function called from a class object

Hello I have the following code;您好,我有以下代码;

I am trying to test the load function inside file_a;我正在尝试在 file_a 中测试负载 function; download is function in an external module I imported在我导入的外部模块中下载的是 function

file_a.py

from foo import download

class Bar()
    __init__(self, arg_1):
        self.var = arg_1

    def load(self):
        if self.var == "latest_lib":
            download("latest_lib")

I wrote the test like我写了这样的测试

test.py

@patch(file_a.download)
def test_download():
    import file_a
    bar = file_a.Bar("latest_lib")
    bar.load()
    file_a.download.assert_called() 

But it seems like the bar object is not calling the mock download rather the imported download.但似乎酒吧 object 没有调用模拟下载,而是调用了导入的下载。 How can I fix this problem and make my test pass?我怎样才能解决这个问题并使我的测试通过?

I tried to use your own code to see where was wrong.我试着用你自己的代码来看看哪里出了问题。 There were some syntax errors which doesn't really matter, but the main issue is that you should pass strings to patch to make it work.有一些语法错误并不重要,但主要问题是您应该将字符串传递给patch以使其工作。

Here's my modification to your code that made it all happen:这是我对您的代码的修改,这一切都发生了:

# file_a.py

from pprint import pprint as pp

class Bar():
    def __init__(self, arg_1):
        self.var = arg_1

    def load(self):
        if self.var == "latest_lib":
            pp("latest_lib")

And:和:

# test_file_a.py

import unittest
from unittest.mock import patch


class TestStringMethods(unittest.TestCase):
    @patch("file_a.pp")
    def test_download(self, pp):
        import file_a
        bar = file_a.Bar("latest_lib")
        bar.load()
        pp.assert_called()


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

NOTES:笔记:

  1. You need to pass a string to patch to make it mock the object in runtime.您需要将字符串传递给patch以使其在运行时模拟 object。
  2. You have to receive the mocked object inside your test function.您必须在测试 function 中收到模拟的 object。
  3. I have used class-based tests here because I wanted to work with the unittest standard library, but you don't have to do the same if you're using pytest .我在这里使用了基于类的测试,因为我想使用unittest标准库,但是如果您使用的是pytest ,则不必这样做。

Also one final note from the official doc :还有来自官方文档的最后一条说明:

The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.基本原则是在查找 object 的地方打补丁,这不一定与定义的地方相同。

I think you are missing the mock setup:我认为您缺少模拟设置:

@patch("foo.download")
def test_download(mock_download):
    from file_a import Bar

    Bar("latest_lib").load()
    mock_download.assert_called()

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

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