[PYTHON] I tried to summarize the frequently used implementation method of pytest-mock

I checked how to use pytest-mock, so make a note Since it is troublesome to check the use cases that are likely to be used in the future, I summarized them. It's an article I wrote in a day after I checked pytest, so I think there are various excesses and deficiencies, but if I find a better way, I will update it as needed.

About pytest and pytest-mock

It is one of the libraries used when implementing python test code. Please refer to the official website for details.

pytest https://docs.pytest.org/en/latest/index.html

pytest-mock https://pypi.org/project/pytest-mock/

Method used for explanation

The following hoge method is the test target.

from mailer import Mailer

#example messages
# ['1st text', 'Second text']
def hoge(messages):
    try:
        #Send as many emails as there are messages
        for message in messages:
          has_error = Mailer.send(message)
          if has_error:
            #1 is returned when an error occurs
            return 1

        #Returns 0 at the end of normal
        return 0
    except Exception as e:
        #2 is returned when an exception occurs
        return 2

The version used at the time of writing this article is as follows.

Replace Mailer.send with a mock

test_hoge.py


from hoge import hoge
from mailer import Mailer
from unittest.mock import call

def test_hoge(mocker):
    # Mailer.Replace send with mock
    mailer_mock = mocker.patch.object(Mailer, 'send')

    messages = ['1st text', 'Second text']

    #Mailer above.Since send is a mock, even if you execute hoge, it is a real Mailer.send will not be executed
    assert hoge(messages) == 0

I want to verify the number of calls

test_hoge.py


from hoge import hoge
from mailer import Mailer
from unittest.mock import call

def test_hoge(mocker):
    # Mailer.Replace send with mock
    mailer_mock = mocker.patch.object(Mailer, 'send')

    messages = ['1st text', 'Second text']
    assert hoge(messages) == 0

    # Mailer.You can see that send is called twice
    assert mailer_mock.call_count == 2

I want to verify that it is not called

test_hoge.py


from hoge import hoge
from mailer import Mailer
from unittest.mock import call

def test_hoge(mocker):
    # Mailer.Replace send with mock
    mailer_mock = mocker.patch.object(Mailer, 'send')

    #Since messages are empty, Mailer. prevent send from being called
    messages = []
    assert hoge(messages) == 0

    # Mailer.Verify that send is not called
    mailer_mock.assert_not_called()

I want to verify the parameters

test_hoge.py


from hoge import hoge
from mailer import Mailer
from unittest.mock import call

def test_hoge(mocker):
    # Mailer.Replace send with mock
    mailer_mock = mocker.patch.object(Mailer, 'send')

    messages = ['1st text', 'Second text']
    assert hoge(messages) == 0

    #The first time'1st text', The second time'Second text'Can be verified that is being passed and called as a parameter
    mailer_mock.assert_has_calls([call('1st text'), call('Second text')])

I want to control the return value

test_hoge.py


from hoge import hoge
from mailer import Mailer
from unittest.mock import call

def test_hoge(mocker):
    # side_Pass a list of return values as an array to effect
    #Each time it is called, it will be returned in order from the beginning of the array
    #In this example, False is returned the first time and True is returned the second time.
    mailer_mock = mocker.patch.object(Mailer, 'send', side_effect = [False, True])

    messages = ['1st text', 'Second text']

    #Second Mailer.Since send returns True, you can verify the return value 1.
    assert hoge(messages) == 1

I want to raise an exception

test_hoge.py


from hoge import hoge
from mailer import Mailer
from unittest.mock import call

def test_hoge(mocker):
    # side_Specify an exception for effect
    #In this example, the first time is False and the second time is an exception.
    mailer_mock = mocker.patch.object(Mailer, 'send', side_effect = [False, Exception('error')])

    messages = ['1st text', 'Second text']

    #Second Mailer.Since send raises an exception, the return value 2 can be verified.
    assert hoge(messages) == 2

Recommended Posts

I tried to summarize the frequently used implementation method of pytest-mock
I tried to summarize the basic form of GPLVM
I tried to summarize the string operations of Python
I tried to summarize the code often used in Pandas
I tried to summarize the commands often used in business
[Machine learning] I tried to summarize the theory of Adaboost
I tried to summarize the umask command
I tried to summarize the graphical modeling.
I tried to summarize the commands used by beginner engineers today
I tried to correct the keystone of the image
LeetCode I tried to summarize the simple ones
I tried to predict the price of ETF
I tried to vectorize the lyrics of Hinatazaka46!
I tried to summarize the logical way of thinking about object orientation.
[Linux] I tried to verify the secure confirmation method of FQDN (CentOS7)
I tried to summarize the Linux commands used by beginner engineers today-Part 1-
I tried to summarize how to use matplotlib of python
I tried to summarize the settings for various databases of Django (MySQL, PostgreSQL)
I tried to summarize the operations that are likely to be used with numpy-stl
I tried to visualize the spacha information of VTuber
I tried to erase the negative part of Meros
I tried to summarize SparseMatrix
I tried to simulate the dollar cost averaging method
I didn't understand the Resize of TensorFlow so I tried to summarize it visually.
I tried the simplest method of multi-label document classification
I tried to classify the voices of voice actors
[Python] I tried to summarize the array, dictionary generation method, loop method, list comprehension notation
I tried to find the entropy of the image with python
[Horse Racing] I tried to quantify the strength of racehorses
[First COTOHA API] I tried to summarize the old story
I tried to get the location information of Odakyu Bus
I tried to find the average of the sequence with TensorFlow
[Python] I tried to visualize the follow relationship of Twitter
I tried to fight the Local Minimum of Goldstein-Price Function
I tried to summarize how to use the EPEL repository again
I tried to move the ball
I tried to estimate the interval.
I tried using the frequently used seaborn method with as few arguments as possible [for beginners]
Implementation of recommendation system ~ I tried to find the similarity from the outline of the movie using TF-IDF ~
I want to get the name of the function / method being executed
I tried to get the index of the list using the enumerate function
I tried to automate the watering of the planter with Raspberry Pi
I tried to build the SD boot image of LicheePi Nano
I tried to expand the size of the logical volume with LVM
I used the worldcup command to check the outcome of the World Cup.
I tried to improve the efficiency of daily work with Python
I tried to visualize the common condition of VTuber channel viewers
I tried to create a linebot (implementation)
I tried to summarize Python exception handling
I tried the asynchronous server of Django 3.0
Python3 standard input I tried to summarize
I tried adding post-increment to CPython Implementation
I tried to estimate the pi stochastically
I tried to touch the COTOHA API
I tried to summarize the contents of each package saved by Python pip in one line
I read the implementation of golang channel
I tried to summarize Ansible modules-Linux edition
I tried to make Othello AI with tensorflow without understanding the theory of machine learning ~ Implementation ~
I tried to transform the face image using sparse_image_warp of TensorFlow Addons
[Python] I tried to summarize the set type (set) in an easy-to-understand manner.
I tried to summarize until I quit the bank and became an engineer