2017-01-05 2 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) 

Есть два вопроса. При выполнении этого теста я получаю. (WS является веб-гнездо)

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

и wssender не возвращает ничего, так что я не уверен, что испытать в этом случае.

+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

Я предполагаю, что "класс Worker (Я)" опечатка и что это действительно "класс рабочий (объект)" (или любого другого базового класса).

WRT/первый вопрос, вы забыли создать экземпляр Worker в тесте - вы хотите:

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

никак не связаны, но wssender() не хорошее название для метода - sender является полдень, методы действия и должен использовать глаголы, поэтому wssend() (или просто send() FWIW) было бы лучше.

Теперь со второй проблемой у вас есть пара вариантов. Если то, что вы хотите, чтобы проверить это форматирование сообщения, просто разделить его на другой метод:

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

Смежные вопросы