2017-09-29 15 views
1

シリアルポートからUnicodeテキスト文字列を読み込むPython 3メソッドの単体テストを作成します。さまざまな文字列に対するメソッドのレスポンスをテストしたいと思います。私がエミュレートするコードの行がある:「serial_portは」メソッドに渡されたシリアルポートのインスタンスであるPython 3 unittest mockを使ってシリアルポートからデータをエミュレートするには?

comm_buffer = serial_port.readline().decode("utf-8").strip() 

。 unittest.mockモジュールを使用して、comm_buffer変数をユニコード文字列に設定したいと思いますが、私は一日中苦労して成功していません。モックを使ってみるのは初めてですが、私は自分の奥から外れています。

全体メソッドのコードは次のとおり

def wait_for_data(serial_port, comm_flag = ""): 
"""Read lines of data from the serial_port 

Receives optional comm_flag (single character to check for at beginning of string)""" 
logging.debug("Start wait_for_data " + comm_flag) 
timeout_count = 0 
while True: 
    # Get a line from the buffer and convert to string and strip line feed 
    logging.debug("Waiting for data…") 
    comm_buffer = serial_port.readline().decode("utf-8").strip() 
    if len(comm_buffer) == 0: 
     timeout_count += 1 
     logging.warning("Serial port timeout - no data received. Timeout count = " + str(timeout_count)) 
     if timeout_count > 10: 
      raise TimeoutError(["Too many timeouts"]) 
    # If no id character was specified, just return the string 
    elif comm_flag == "": 
     logging.debug("Returning no comm_flag") 
     return comm_buffer 
    # If an id character was specified, return the string if it's present (strip id), otherwise wait for another string 
    elif comm_buffer[0] == comm_flag: 
     logging.debug("Returning with comm_flag") 
     return comm_buffer[1:] 

答えて

0

Serial_portシリアルポートのインスタンスが、readlineの()メソッドを持つオブジェクトではありません。したがって、シリアルポートのようなものは気にしないでください。あなたのモックオブジェクトは、テストしたい種類の値を提供するreadline()メソッドを持つオブジェクトです。 だから、あなただけのようなクレートに何かする必要があります:

port = Mock() 
port.readline = Mock(return_value="my string") 

これはあなたの呼び出しのための最初のパラメータです。私はこのテストtest.portという名前のモジュールであなたの関数をコピーする場合 だから、大丈夫です:

class TestWaitData(unittest.TestCase): 

    def testFunc(self): 
     port = mock.Mock() 
     port.readline = mock.Mock(return_value="my string".encode('utf-8')) # as you use a decode call 

     self.assertEqual(test.port.wait_for_data(port), "my string") 

    def testBufferEmpty(self): 
     port = mock.Mock() 
     port.readline = mock.Mock(return_value="".encode('utf-8')) 

     with self.assertRaises(TimeoutError): 
      test.port.wait_for_data(port) 

    def testWithFlag(self): 
     port = mock.Mock() 
     port.readline = mock.Mock(return_value="fmy string".encode('utf-8')) 

     self.assertEqual(test.port.wait_for_data(port, 'f'), "my string") 
+0

HI、答えてくれてありがとう。残念ながら、あなたが提案したようにMock()として定義された 'port'を持つメソッドを呼び出すと、そのメソッドでMock()は呼び出されません。代わりに、変数 'c​​omm_buffer'にMock()が代入され、 "TypeError:タイプMockのオブジェクトに2行後にlen()がありません"というエラーでテストが失敗します。 – Martin

+0

多分私は私の答えで誤解していた。私はちょうど動作するテストケース全体を追加しました。私は厳密にこのテストのための関数としてあなたのコードをコピーしました。 –

+0

私は完全なテストクラスを与えるために時間を費やしてくれてありがとう。今は理にかなっている。 – Martin

関連する問題