134 votes

Comment simuler une propriété en lecture seule avec mock ?

Comment faire pour simuler une propriété en lecture seule avec simuler ?

J'ai essayé :

setattr(obj.__class__, 'property_to_be_mocked', mock.Mock())

mais le problème est qu'il s'applique alors à toutes les instances de la classe... ce qui casse mes tests.

Vous avez une autre idée ? Je ne veux pas simuler l'objet complet, seulement cette propriété spécifique.

3voto

Conchylicultor Points 984

Si vous avez besoin de votre maquette @property de s'appuyer sur l'original __get__ vous pouvez créer votre propre MockProperty

class PropertyMock(mock.Mock):

    def __get__(self, obj, obj_type=None):
        return self(obj, obj_type)

Utilisation :

class A:

  @property
  def f(self):
    return 123

original_get = A.f.__get__

def new_get(self, obj_type=None):
  return f'mocked result: {original_get(self, obj_type)}'

with mock.patch('__main__.A.f', new_callable=PropertyMock) as mock_foo:
  mock_foo.side_effect = new_get
  print(A().f)  # mocked result: 123
  print(mock_foo.call_count)  # 1

1voto

Simon Charette Points 490

Si vous ne voulez pas tester si la propriété simulée a été accédée ou non, vous pouvez simplement la remplacer par la propriété attendue. return_value .

with mock.patch(MyClass, 'last_transaction', Transaction()):
    ...

0voto

mike rodent Points 482

J'ai été dirigé vers cette question parce que je voulais simuler la version Python dans un test. Je ne suis pas sûr que cela soit tout à fait pertinent pour cette question, mais sys.version est évidemment en lecture seule (... bien que techniquement un "attribut" plutôt qu'une "propriété", je suppose).

Donc, après avoir parcouru cet endroit et essayé des trucs stupidement compliqués, j'ai réalisé que la réponse était la simplicité même :

with mock.patch('sys.version', version_tried):
    if version_tried == '2.5.2':
        with pytest.raises(SystemExit):
            import core.__main__
        _, err = capsys.readouterr()
        assert 'FATAL' in err and 'too old' in err

... pourrait aider quelqu'un.

0voto

Une autre façon d'utiliser les propriétés des objets fantaisie est la suivante :

import mock

mocked_object = mock.Mock()
mocked_object.some_property = "Property value"

print(mocked_object.some_property)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X