Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

comment mocker un service externe et que coverage le prenne en compte

+2 votes

Hello,

j'ai parcouru à peu près tout ce qu'on peut trouver sur mock mais je sèche. par exemple https://www.toptal.com/python/an-introduction-to-mocking-in-python

Comment peut on mocker un service externe appelé dans une fonction ?
est-ce que coverage prend en compte la partie du code "mocké" ?

genre

def read_data(self, **kwargs):
    .... du code ....
    note_store = self.evernote.get_note_store() 

je voudrai que coverage me sorte que tout read_data soit à 100% d'une part et d'autre part je voudrai que mock se charge de evernote

pour l'heure je suis passé par ces tests là :

def test_read_data(self):
    kwargs = dict({'date_triggered': arrow.get('2013-05-11 13:23:58'),
                   'trigger_id': self.trigger_id,
                   'model_name': 'Evernote'})

    with patch.object(ServiceEvernote, 'read_data', return_value={}) as mock_method:
        se = ServiceEvernote(self.token)
        se.read_data(**kwargs)
    mock_method.assert_called_once_with(**kwargs)

    with patch.object(EvernoteClient, 'get_note_store', return_value=[]) as mock_method:
        ev = EvernoteClient()
        ev.get_note_store()
    mock_method.assert_called_once_with()

ca produit aucune erreur mais "coverage" m'ignore allègrement TOUT read_data ...
et en plus j'ai l'impression de foutre du mock sur EvernoteClient mais pas depuis read_data

demandé 10-Jul-2016 par foxmask (2,888 points)

2 Réponses

0 votes
 
Meilleure réponse

Pour que ca marche il faut, non pas mocker read_data (qui est la méthode qui contient la fonction que je veux mocker), mais bien l'une des methodes appelées dans cette methode, ici get_evernote_notes
Ce qui donne donc

def test_read_data(self):
    kwargs = dict({'date_triggered': '2013-05-11 13:23:58+00:00',
                   'trigger_id': self.trigger_id})

    with patch.object(ServiceEvernote, 'get_evernote_notes') as mock_get_evernote_notes:
        se = ServiceEvernote(self.token)
        se.read_data(**kwargs)
    mock_get_evernote_notes.assert_called_once()

comme je suis pas un dieu du test unitaire, je sais pas comment on utilise plusieurs manager, donc si on veut mocker plusieurs méthodes appelées depuis une fonction, on fera avec un décorateur :

@patch.object(ServiceEvernote, 'set_note_filter')
@patch.object(ServiceEvernote, 'get_evernote_notes')
def test_read_data(self, mock1, mock2):
    kwargs = dict({'date_triggered': '2013-05-11 13:23:58+00:00',
                   'trigger_id': self.trigger_id})

    se = ServiceEvernote(self.token)
    se.read_data(**kwargs)
    se.get_evernote_notes()
    se.set_note_filter()
    mock1.assert_called_once()
    mock2.assert_called_once()
répondu 21-Oct-2016 par foxmask (2,888 points)

j'en ai fait un article

Hééééé oui , j'ai ENCORE repondu à ma propre QUESTION ... zetes pas SERVIABLES :D

0 votes

coverage.py peut ignorer certains blocs de code:
http://coverage.readthedocs.io/en/coverage-4.2b1/excluding.html#excluding

Excluded code is executed as usual, and its execution is recorded in the coverage data as usual. When producing reports though, coverage.py excludes it from the list of missing code.

def read_data(self, **kwargs): # pragma: nocover
      ...

Il est aussi possible d'ignorer tout un fichier:
http://coverage.readthedocs.io/en/coverage-4.2b1/source.html#source

répondu 12-Jul-2016 par iCart (130 points)

Merci pour la reponse pour coverage
Mais pour mock ? Comment faire pour tester read_data et y mocker self.evernote.get_note_store ?

Parce que si je mock read_data , j'y teste rien :/

Je m'y prends peut-etre comme un manche

...