简体   繁体   English

Python:模拟导入的模块方法

[英]Python: mock imported module method

I have to test if the method pyautogui.click() is called. 我必须测试是否调用了pyautogui.click()方法。 This is my Player.py file: 这是我的Player.py文件:

# Player.py

import pyautogui

class Player:
    def play():
        pyautogui.click(100, 100)

And this is my test file: 这是我的测试文件:

# Test_Player.py

import unittest
from Player import Player

class Test_Player(unittest.TestCase):
    def test_play(self):
        player = Player()
        player.play()
        # assert pyautogui.click is called once

I tried with pyautogui.click = MagicMock() and also many other things but I really cannot find how to assert that pyautogui.click() is called once. 我尝试使用pyautogui.click = MagicMock()以及其他许多方法,但是我真的找不到如何断言pyautogui.click()被调用一次的方法。

You're looking for unittest.mock.patch . 您正在寻找unittest.mock.patch Patch replaces an imported module with a mock version for the duration of a test. 在测试期间,Patch用模拟版本替换了导入的模块。 The most important thing to understand about it is that you have to patch something where it is imported , not where it lives. 要了解的最重要的一点是,您必须在导入的地方而不是在其居住的地方打补丁。 That means you patch Player.pyautogui , not pyautogui itself. 这意味着您修补Player.pyautogui ,而不是pyautogui本身。 You should read "Where to Patch" in the docs. 您应该阅读文档中的“修补程序”

You can add the patch decorator to your test function and pass it what you want to replace with a mock. 您可以将补丁装饰器添加到您的测试函数中,然后将其替换为您想要的模拟内容。 The string you pass it should be a relative path from where you're running your tests (usually the root directory of your project). 传递的字符串应该是您运行测试的相对路径(通常是项目的根目录)。 I'll assume both of your files are in the same folder, and you run your tests from that folder. 我假设两个文件都在同一个文件夹中,并且您从该文件夹运行测试。

The patch decorator will then pass your test function an instance of MagicMock as the argument after self . 然后,补丁装饰器将在您的测试函数中通过MagicMock实例作为self后面的参数。 You can name it whatever you'd like. 您可以随意命名。 I'll call it mock_pyautogui in the sample below. 在下面的示例中,我将其称为mock_pyautogui Inside your function, you can make assertions like you normally would. 在函数内部,您可以像通常那样进行断言。

import unittest
from Player import Player

class Test_Player(unittest.TestCase):

    @unittest.mock.patch("Player.pyautogui")
    def test_play(self, mock_pyautogui):
        player = Player()
        player.play()

        self.assertEqual(1, mock_pyautogui.click.call_count)

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

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