Giovanni Improta
Giovanni Improta

Reputation: 55

Python: mock imported module method

I have to test if the method pyautogui.click() is called. This is my Player.py file:

# 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.

Upvotes: 3

Views: 8440

Answers (1)

lortimer
lortimer

Reputation: 710

You're looking for unittest.mock.patch. Patch replaces an imported module with a mock version for the duration of a test. 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. 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. You can name it whatever you'd like. I'll call it mock_pyautogui in the sample below. 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)

Upvotes: 5

Related Questions