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.

Valutazione

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

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.

Descrizione

docs stdlib type-bug

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

Lingua principale
Python
Stelle
77.2k
Fork
36k
Merge medio
1g 9h
PR unite (30g)
558

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.

Altre issue di python/cpython

Tutte le issue di python/cpython

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.