python / python/cpython

side_effect function of PropertyMock gets called only once

Ouverte
#94,323 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

docs stdlib type-bug
Langage dominant
Python
Étoiles
77.2k
Forks
36k
Merge moyen
1 j 9 h
PR mergées (30 j)
558

Description

Bug report

Expected behavior

The side_effect function of a PropertyMock should work like the side_effect function of other Mock-Objects

Seen behavior

side_effect function of PropertyMock is called only once instead of twice in below example.

Minimal example

File dut.py:

class Class1():
    def __init__(self, name):
        self.__name = name

    @property
    def name(self):
        return self.__name

    def name_func(self):
        return self.__name


class Class2():
    def __init__(self, name, class1):
        self.__name = name
        self.__class1 = class1

    @property
    def name(self):
        return self.__name
    @property
    def class1(self):
        return self.__class1

File test\test_dut.py:

import dut
import unittest
from unittest.mock import patch, PropertyMock

class TestClass2(unittest.TestCase):
    def test_func(self):
        side_effect_counter = -1
        def side_effect_func(_):
            nonlocal side_effect_counter
            side_effect_counter += 1
            return f'text_{side_effect_counter}'

        c2_1 = dut.Class2('class2',  dut.Class1('class1'))
        c2_2 = dut.Class2('class2_2', dut.Class1('class1_2'))
        with patch('test_dut.dut.Class1.name_func', side_effect=side_effect_func, autospec=True):
            print(f'{c2_2.class1.name_func()}, {c2_1.class1.name_func()}')

    def test_prop(self):
        side_effect_counter = -1
        def side_effect_func():
            nonlocal side_effect_counter
            side_effect_counter += 1
            return f'text_{side_effect_counter}'

        c2_1 = dut.Class2('class2',  dut.Class1('class1'))
        c2_2 = dut.Class2('class2_2', dut.Class1('class1_2'))
        with patch.object(dut.Class1, 'name', new_callable=PropertyMock(side_effect=side_effect_func)):
            print(f'{c2_2.class1.name}, {c2_1.class1.name}')

Call from command line: pytest -rP test\test_dut.py

This produces the following output (problematic line marked by me):

============================================================================================== test session starts ==============================================================================================
platform win32 -- Python 3.9.12, pytest-7.1.2, pluggy-1.0.0
rootdir: C:\Users\klosemic\Documents\playground_mocks
plugins: hypothesis-6.46.5, cov-3.0.0, forked-1.4.0, html-3.1.1, metadata-2.0.1, xdist-2.5.0
collected 2 items

test\test_dut.py ..                                                                                                                                                                                        [100%]

==================================================================================================== PASSES =====================================================================================================
_____________________________________________________________________________________________ TestClass2.test_func ______________________________________________________________________________________________
--------------------------------------------------------------------------------------------- Captured stdout call ----------------------------------------------------------------------------------------------
text_0, text_1
_____________________________________________________________________________________________ TestClass2.test_prop ______________________________________________________________________________________________
--------------------------------------------------------------------------------------------- Captured stdout call ----------------------------------------------------------------------------------------------
text_0, text_0 <<<<<< HERE IS THE PROBLEM
=============================================================================================== 2 passed in 0.46s ===============================================================================================

Your environment
Windows 10, Python 3.9.12.
More version information can be found in the output of example above

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par reproduire le problème avec le dut.py fourni et l’exemple test/test_dut.py, en comparant PropertyMock avec le cas fonctionnel Mock side_effect. Suivez le comportement de unittest.mock PropertyMock et ajoutez un test de régression montrant que la fonction side_effect s’exécute à chaque accès à la propriété, puis exécutez la commande pytest fournie.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
testing-qa
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
42/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.