[PYTHON] Compter / vérifier le nombre d'appels de méthode.

Cela dépend de l'extrait de code (http://qiita.com/items/1321) que j'ai mentionné plus tôt. Il compte / valide les appels de méthode dans les tests.

from unittest import TestCase


class CallCounter(object):
    """Check a numbe of time a callable is called."""

    def __new__(cls, *args, **kargs):
        inst = super(CallCounter, cls).__new__(cls, *args, **kargs)
        inst._patch_mgr = PatchManager()
        inst._targets = {}
        return inst

    class FailedVerification(Exception):
        pass

    class CallCountManager(object):
        def __init__ (self, target, name, expected):
            self.__target = target
            self.__name = name
            self.__original = getattr(target, name)
            self.__count = 0
            self.__expected = expected

        def __call__(self, *args, **kargs):
            self.__count += 1
            return self.__original(*args, **kargs)

        def __verify(self):
            if self.__count == self.__expected:
                return

            msg = '%s.%s should be called %d times but %d' % \
                  (self.__target.__name__, self.__name, self.__expected,
                   self.__count,)
            raise CallCounter.FailedVerification(msg)

    def ensure(self, target, name, count):
        counter = self.CallCountManager(target, name, count)
        key = '%s.%s'%(target.__name__, name)
        self._targets[key] = counter
        self._patch_mgr.attach(target, name, counter)
        return

    def verify(self):
        for key, counter in self._targets.iteritems():
            counter._CallCountManager__verify()
        return

    def end(self):
        self._patch_mgr.detach_all()
        return

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end()
        if exc_type:
            return False
        return True


class TestCallCounter(TestCase):
    """Test for test.CallCounter."""

    def test_1(self):
        """Call it simply."""

        c = CallCounter()

        import datetime
        original = datetime.datetime
        c.ensure(datetime, 'datetime', 1)
        self.assert_(isinstance(datetime.datetime,
                                CallCounter.CallCountManager))
        self.assertNotEqual(datetime.datetime, original)

        # Call it first.
        datetime.datetime(year=2011, month=3, day=4)
        c.verify()

        # Call it second.
        datetime.datetime(year=2011, month=3, day=4)
        with self.assertRaises(CallCounter.FailedVerification):
            c.verify()

        # Verify a clearance.
        c.end()
        self.assertEqual(datetime.datetime, original)

        return

    def test_2(self):
        """Call it simply."""

        c = CallCounter()

        import datetime
        original = datetime.datetime
        c.ensure(datetime, 'datetime', 0)
        self.assertNotEqual(datetime.datetime, original)

        # Call it and verify.
        datetime.datetime(year=2011, month=3, day=4)
        with self.assertRaises(CallCounter.FailedVerification):
            c.verify()

        c.end()
        self.assertEqual(datetime.datetime, original)

        return

    def test_3(self):
        """Use it with `with statement`."""

        import datetime
        original = datetime.datetime
        with self.assertRaises(CallCounter.FailedVerification):
            with CallCounter() as c:
                c.ensure(datetime, 'datetime', 0)
                self.assertNotEqual(datetime.datetime, original)

                # Call it and verify.
                datetime.datetime(year=2011, month=3, day=4)
                c.verify()

        self.assertEqual(datetime.datetime, original)

        return

    def test_4(self):
        """Exception is happend in with statement."""

        import datetime
        original = datetime.datetime
        with self.assertRaises(AssertionError):
            with CallCounter() as c:
                c.ensure(datetime, 'datetime', 0)
                self.assertNotEqual(datetime.datetime, original)

                # Call it and verify.
                datetime.datetime(year=2011, month=3, day=4)
                raise AssertionError()

        self.assertEqual(datetime.datetime, original)

        return

Recommended Posts

Compter / vérifier le nombre d'appels de méthode.
Compter le nombre de caractères avec écho
10. Compter le nombre de lignes
Comptez le nombre de paramètres dans le modèle d'apprentissage en profondeur
Obtenez le nombre de chiffres
Calculez le nombre de changements
Comptez le nombre de caractères dans le texte dans le presse-papiers sur Mac
[Homologie] Comptez le nombre de trous dans les données avec Python
Obtenez le nombre de vues de Qiita
Calcul du nombre d'associations de Klamer
Obtenez le nombre d'abonnés Youtube
Comptez bien le nombre de caractères thaïlandais et arabes en Python
J'ai étudié la méthode X-means qui estime automatiquement le nombre de clusters
[Linux] J'ai essayé de vérifier la méthode de confirmation sécurisée du FQDN (CentOS7)
4 méthodes pour compter le nombre d'occurrences d'entiers dans un certain intervalle (y compris la méthode imos) [implémentation Python]
Sortie du nombre de cœurs de processeur en Python
À propos de la précision de la méthode de calcul du rapport de circonférence d'Archimède
Clustering de méthodes de clustering
Calculez le nombre total de combinaisons avec python
Comment compter le nombre d'éléments dans Django et sortir dans le modèle
Divisez la chaîne de caractères en le nombre de caractères spécifié
Trouvez le nombre de jours dans un mois
Minimisez le nombre de polissages en optimisant la combinaison
Déterminez le nombre de classes à l'aide de la formule Starges
Comment compter le nombre d'occurrences de chaque élément de la liste en Python avec poids
Vérifiez le temps de traitement et le nombre d'appels pour chaque processus avec python (cProfile)
Calcul de l'itinéraire le plus court selon la méthode de Monte Carlo
[Python] Un programme qui compte le nombre de vallées
Projecet Euler 12 Trouvez le nombre de fractions sans diviser.
Comment obtenir le nombre de chiffres en Python
relation entre la série de nombres de Fibonacci et le nombre d'or
Calcul du nombre minimum de voix requis à partir du taux de vote
Détruire l'expression intermédiaire de la méthode sweep avec Python
Essayez d'estimer le nombre de likes sur Twitter
Prédire le nombre de personnes infectées par COVID-19 avec Prophet
Obtenir la taille (nombre d'éléments) de Union Find en Python
[Résumé de 27 langues] Méthode de calcul des chiffres de contrôle de mon numéro
Gérez le numéro de version du package de requirements.txt avec pip-tools
[Python] Obtenez le nombre de vues de tous les articles publiés
J'ai essayé la méthode la plus simple de classification de documents multi-étiquettes
Visualisez le nombre de plaintes des compagnies d'assurance-vie
La méthode de copie de pandas.DataFrame est une copie profonde par défaut
Clustering G-means qui détermine automatiquement le nombre de clusters
Le début de cif2cell
Le sens de soi
le zen de Python
L'histoire de sys.path.append ()
Résumé de la méthode d'essai
La vengeance des types: la vengeance des types
Augmentez la vitesse de la méthode Monte Carlo de l'implémentation de découpage Cython.
Comment trouver le nombre optimal de clusters pour les k-moyennes
Maya | Découvrez le nombre de polygones dans l'objet sélectionné
Une implémentation Python simple de la méthode k-voisinage (k-NN)
Examiner la plage d'erreur dans le nombre de décès dus à la pneumonie
Obtenez le nombre d'éléments spécifiques dans la liste python
Python --Trouvez le nombre de groupes dans l'expression regex
Décorateur qui affiche "Nom de la méthode FIN" à la fin de la méthode