Setzen Sie die Schlüsselwortargumente des Konstruktors auf die Scheinattribute in Python

Ich teste eine Klasse, die peewee für ORM verwendet. Ich habe mock für den Test verwendet und versucht zu überprüfen, ob der richtige Wert für das Attribut des Modells festgelegt wurde, aber was ich für das Attribut im Konstruktor des Modells festgelegt habe Bei der Übergabe als Argument mit einem Schlüsselwort konnte die mock.Mock-Klasse nicht so gut getestet werden, wie sie ist. Daher habe ich ein mock erstellt, das das Argument mit einem Schlüsselwort auf ein Attribut setzt.

Übrigens bin ich in Python erst zwei Monate alt, und ich habe möglicherweise einen großen Fehler gemacht, und es gibt möglicherweise einen intelligenteren Weg. Wenn jemand Fehler oder bessere Wege kennt, wäre er sehr dankbar, wenn Sie einen Kommentar abgeben könnten.

Nachtrag vom 15.10.2016 Der Code in diesem Artikel unterstützt nur den Fall, dass nur ein Mock erstellt wird. Bei mehreren Instanziierungen müssen Sie im Kommentar eine Methode wie @ podhmos beispielhafter Code verwenden.

Umgebung

Vorbereitung

$ pip install peewee
$ pip install mock

Verzeichnisaufbau

$ tree
.
├── src
│   ├── __init__.py
│   ├── model.py
│   └── service.py
└── test
    ├── __init__.py
    └── test_service.py

Zu testender Code

src/service.py


# -*- coding: utf-8 -*-

from model import HogeModel

class HogeService(object):
    def run(self):
        model = HogeModel(name='hoge name')
        model.desc = 'hoge desc'
        model.save()

src/model.py


# -*- coding: utf-8 -*-

from peewee import SqliteDatabase
from peewee import Model
from peewee import PrimaryKeyField
from peewee import CharField

db = SqliteDatabase('hoge.db')

class HogeModel(Model):
    id = PrimaryKeyField
    name = CharField()
    desc = CharField()

    class Meta:
        database = db

Testcode

test/test_service.py


# -*- coding: utf-8 -*-

import unittest
from mock import patch
from mock import Mock
from service import HogeService

class TestHogeService(unittest.TestCase):

    @patch('service.HogeModel')
    def test_run(self, mock_hoge_model):
        mock = Mock()
        mock_hoge_model.return_value = mock
        target = HogeService()
        target.run()
        self.assertEquals(1, mock.save.call_count)  # OK
        self.assertEquals('hoge desc', mock.desc)  # OK
        self.assertEquals('hoge name', mock.name)  # NG

if __name__ == '__main__':
    unittest.main()
$ PYTHONPATH=src python test/test_service.py 
F
======================================================================
FAIL: test_run (__main__.TestHogeService)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/otti/.pyenv/versions/2.7.12/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
    return func(*args, **keywargs)
  File "test/test_service.py", line 18, in test_run
    self.assertEquals('hoge name', mock.name)  # NG
AssertionError: 'hoge name' != <Mock name='HogeModel().name' id='4454023888'>

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

Setzen Sie das Schlüsselwortargument des Konstruktors auf das Mock-Attribut

test/test_service.py


# -*- coding: utf-8 -*-

import unittest
from mock import Mock
from mock import patch
from service import HogeService

class TestHogeService(unittest.TestCase):

    def create_attr_set_mock(self, **kwargs):
        self.mock = Mock()
        #Setzen Sie das im Konstruktor übergebene Schlüsselwortargument auf das Attribut
        for k, v in kwargs.items():
            self.mock.__dict__[k] = v
        return self.mock

    @patch('service.HogeModel')
    def test_run(self, mock_hoge_model):
        #Gibt ein Modell zurück, das beim Instanziieren der Zielklasse ein Attribut mit einem Schlüsselwortargument im Konstruktor festlegt
        mock_hoge_model.side_effect = lambda **kwargs: self.create_attr_set_mock(**kwargs)
        target = HogeService()
        target.run()
        self.assertEquals(1, self.mock.save.call_count) # OK
        self.assertEquals('hoge desc', self.mock.desc) # OK
        self.assertEquals('hoge name', self.mock.name) # OK

if __name__ == '__main__':
    unittest.main()
 PYTHONPATH=src python test/test_service.py 
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

Jetzt haben Sie ein Modell, das wie erwartet funktioniert. Es war ein bisschen verwirrend, weil mock.Mock an erster Stelle ein Attribut namens name zu haben scheint, aber es war das gleiche, auch wenn ich es mit anderen Attributen als name versucht habe.

Referenz

Recommended Posts

Setzen Sie die Schlüsselwortargumente des Konstruktors auf die Scheinattribute in Python
So empfangen Sie Befehlszeilenargumente in Python
So legen Sie Attribute mit Mock of Python fest
Ich möchte in Python schreiben! (3) Verwenden Sie Mock
So löschen Sie stdout in Python
Melden Sie sich auf der Website in Python an
Empfangen Sie Laufzeitargumente in Python 2.7
Sprechen mit Python [Text zu Sprache]
Wie man in Python entwickelt
Post an Slack in Python
Stellen Sie den Python-Test in Jenkins ein
So importieren Sie die in EFS eingerichtete Python-Bibliothek in Lambda
Dinge, auf die Sie achten müssen, wenn Sie Standardargumente in Python verwenden
[Python] Wie man PCA mit Python macht
Übergeben von Argumenten an Python-Skripte in SPSS Modeler Batch
Inklusive Notation im Argument der Python-Funktion
Konvertieren Sie Markdown in Python in PDF
So sammeln Sie Bilder in Python
Verwendung von SQLite in Python
Im Python-Befehl zeigt Python auf Python3.8
Versuchen Sie, Trace in Python zu berechnen
Wie man MySQL mit Python benutzt
So verpacken Sie C in Python
Verwendung von ChemSpider in Python
6 Möglichkeiten zum Stringen von Objekten in Python
Verwendung von PubChem mit Python
Übergeben Sie Argumente in discord.py an Task
Vorsichtsmaßnahmen beim Festlegen von Standardwerten für Argumente in Python-Funktionsdefinitionen
Umgang mit Japanisch mit Python
Eine Alternative zu "Pause" in Python
[Python] Ich habe versucht, den kollektiven Typ (Satz) auf leicht verständliche Weise zusammenzufassen.
Ich habe versucht, PLSA in Python zu implementieren
[Einführung in Python] Wie verwende ich eine Klasse in Python?
Versuchen Sie, sich mit Python bei qiita anzumelden
Installieren Sie Pyaudio, um Wellen in Python zu spielen
Ich habe versucht, Permutation in Python zu implementieren
Methode zum Erstellen einer Python-Umgebung in Xcode 6
Dynamisches Definieren von Variablen in Python
So machen Sie R chartr () in Python
Pin aktuelles Verzeichnis an Skriptverzeichnis in Python
[Itertools.permutations] So löschen Sie eine Sequenz in Python
PUT gzip direkt in S3 in Python
Senden Sie mit Python (Python3) E-Mails an mehrere Empfänger.
Konvertieren Sie die psd-Datei in Python in png
Beispielskript zum Überfüllen von Signalen in Python
Dekorateur zur Vermeidung von UnicodeEncodeError in Python 3 print ()
So arbeiten Sie mit BigQuery in Python
Ordnen Sie die in pythons models.py festgelegte Tabelle zu
Melden Sie sich mit Anforderungen in Python bei Slack an
Wie bekomme ich Stacktrace in Python?
So zeigen Sie die neunundneunzig Tabelle in Python an
Einfache Möglichkeit, Wikipedia mit Python zu verwenden
So extrahieren Sie einen Polygonbereich in Python
So überprüfen Sie die Version von opencv mit Python
Ich habe versucht, ADALINE in Python zu implementieren
[Python] Pandas in 10 Minuten vollständig zu verstehen
Werfen Sie Incoming Webhook in Python auf Mattermost
Modul zum Generieren des Wortes N-Gramm in Python
Verweisen auf Umgebungsvariablen in Python in Blender