2017-01-05 4 views
0

Wie würden Sie eine einfache Methode testen, die eine andere Methode aufruft? Ich versuche, die wssender Methode zurzeit zu prüfen.Unit_test eine Methode, die eine andere Methode aufruft, die der Komponententest nicht kennt

in worker.py 
---------------- 
class Worker(self): 
    def __init__(self, ws) 
     self.ws = ws 

    def wssender(self,str): 
     newstr = '<br>{0}'.format(str) 
     self.ws.sendMessage(newstr.encode()) 

und der Testcode

in unit_test.py 
----------------- 
class SimpleTest(unittest.TestCase): 
    def test_wssender(self): 
     msg = 'test send message' 
     wss=worker.Worker 
     wss.wssender(wss, msg) 
     expected = "<br>test send message" 
     self.assertEqual(<something>, expected) 

Es gibt zwei Probleme. Wenn ich diesen Test durchführe, bekomme ich. (Ws ist eine Web-Buchse)

AttributeError: type object 'Worker' has no attribute 'ws' 

und wssender nichts zurückliefert, so dass ich nicht sicher bin, was in diesem Fall zu prüfen.

+1

Sie injizieren 'ws' (ich nehme Websocket an) als eine Abhängigkeit zu' Worker', was gut ist. Das heißt, Sie können es in Ihrem Testcode durch einen Mock ersetzen und anschließend verifizieren. Sehen Sie sich in [unittest.mock] (https://docs.python.org/3/library/unittest.mock.html) um. – Tagc

+2

'wss = worker.Worker' sollte' wss = worker.Worker (ws) 'sein. Und Sie können 'ws' verspotten. –

Antwort

1

Wie ist das?

import unittest 
from unittest.mock import MagicMock 

class Worker(object): 
    def __init__(self, ws): 
     self.ws = ws 

    def wssender(self, str): 
     newstr = '<br>{0}'.format(str) 
     self.ws.sendMessage(newstr.encode()) 

class WorkerTests(unittest.TestCase): 
    def test_wssender(self): 
     # Arrange 
     ws = MagicMock() 
     ws.sendMessage = MagicMock() 
     worker = Worker(ws) 

     # Act 
     worker.wssender('test send message') 

     # Assert 
     ws.sendMessage.assert_called_once_with(b'<br>test send message') 

if __name__ == '__main__': 
    unittest.main() 

Ausgabe

. 
---------------------------------------------------------------------- 
Ran 1 test in 0.000s 

OK 
+0

Dies funktioniert und es hilft mir, Spott besser zu verstehen, so dass ich es auf andere Funktionen (viel komplizierter als diese) ausprobieren kann. Ich verstehe, dass ich Code auf kleinere Funktionen aufteilen und diese testen sollte, aber das ist nützlich für Code, den ich bereits geschrieben habe. – user1601716

1

Ich gehe davon aus "Klasse Arbeiter (Selbst-)" ein Tippfehler ist und dass es wirklich "Klasse Worker (Objekt)" (oder jede andere Basisklasse).

WRT/die erste Ausgabe, vergessen Sie Worker in Ihren Test instanziiert - Sie wollen:

ws = WhateverWsIsSupposedToBe() 
wss=worker.Worker(ws) 
wss.wssender(msg) 

völlig unabhängig, aber wssender() ist kein guter Name für eine Methode - sender ist ein Mittag, Methoden Aktionen und sollte Verben verwenden, so wäre wssend() (oder nur send() FWIW) besser.

Jetzt mit der zweiten Ausgabe, haben Sie ein paar Optionen. Wenn das, was Sie testen wollen, dass die Nachrichtenformatierung ist, teilen Sie es nur in einer anderen Methode:

class Worker(object): 
    def __init__(self, ws) 
     self.ws = ws 

    def prepare(self, msg): 
     return '<br>{0}'.format(msg).encode(...) 

    def send(self, msg): 
     self.ws.sendMessage(self.prepare(msg)) 

so jetzt Sie Worker.prepare(msg) isoliert testen können.

Wenn Sie testen möchten, dass Worker.send(msg) Anrufe self.ws.sendMessage(...) (und es mit dem erwarteten Argument nennt), werden Sie ws verspotten müssen. Sie können dies manuell tun:

class MockWs(object): 
    def __init__(self): 
     self.msg = None 
    def sendMessage(self, msg): 
     self.msg = msg 

class SimpleTest(unittest.TestCase): 
    def test_send(self): 
     ws = MockWs() 
     msg = 'test send message' 
     wss=worker.Worker(ws) 
     wss.send(msg) 
     expected = "<br>test send message" 
     self.assertEqual(ws.msg, expected) 

Oder Sie können die mock Bibliothek, cf Tacg Antwort verwenden.

+0

Dies hilft, hat es funktioniert, in diesem Fall möchte nicht alten Code ändern, aber vorwärts wird versuchen, den Code in kleinere Stücke zu brechen. – user1601716

Verwandte Themen