2017-01-05 10 views
0

別のメソッドを呼び出す単純なメソッドをどのようにテストしますか?私は現在wssenderメソッドをテストしようとしています。Unit_test単体テストが知らない別のメソッドを呼び出すメソッド

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()) 

とテストコード

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) 

2つの問題があります。このテストを実行するときに私は得る。私はこのケースでテストすることはよく分からないので

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

と wssenderは何も返しません(WSは、Webソケットです)。

+1

'ws'(私はwebsocketと仮定しています)を' Worker'への依存として注入しています。つまり、テストコードの疑似コードに置き換えて、検証コードを実行することができます。 [unittest.mock](https://docs.python.org/3/library/unittest.mock.html)を参考にしてください。 – Tagc

+2

'wss = worker.Worker'は' wss = worker.Worker(ws) 'でなければなりません。そしてあなたは 'ws'を模倣することができます。 –

答えて

1

どうやってですか?

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() 

出力

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

OK 
+0

これはうまくいくので、私は他の機能(これよりはるかに複雑)で試すことができます。私は、より小さな関数にコードを分割してそれらをテストする必要があることを理解していますが、これは既に書いたコードには便利です。 – user1601716

1

私は "クラス労働者(自己)" タイプミスであり、それは本当に "クラスの労働者(オブジェクト)"(またはその他の基底クラス)だと仮定します。

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

全く関係のないもののwssender()は、メソッドの良い名前ではありません - senderは正午で、方法はアクションです:あなたが欲しい -

WRT /最初の問題は、あなたのテストでWorkerをインスタンス化するのを忘れ動詞を使用する必要がありますので、wssend()(またはちょうどsend() FWIW)が良いでしょう。

2番目の問題では、いくつかのオプションがあります。何をテストすることはメッセージのフォーマットである場合は、ちょうど別の方法でそれを分割:

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)) 

を今、あなたが孤立してWorker.prepare(msg)をテストすることができます。

Worker.send(msg)self.ws.sendMessage(...)を呼び出して(期待される引数で呼び出す)ことをテストしたい場合は、wsをモックする必要があります。

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) 

をそれとも、mockライブラリ、CF Tacgの答えを使用することができます:あなたはこれを手動で行うことができます。

+0

これは役立ちます。この場合は古いコードを変更したくないですが、今後はコードを小さなチャンクに分解しようとします。 – user1601716

関連する問題