python / python/cpython

side_effect function of PropertyMock gets called only once

Aperta
#94,323 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

docs stdlib type-bug
Lingua principale
Python
Stelle
77.2k
Fork
36k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia riproducendo il problema con il dut.py fornito e l’esempio test/test_dut.py, confrontando PropertyMock con il caso funzionante Mock side_effect. Analizza il comportamento di unittest.mock PropertyMock e aggiungi un test di regressione che mostri che la funzione side_effect viene eseguita a ogni accesso alla proprietà, quindi esegui il comando pytest fornito.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
testing-qa
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
42/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.