嘲弄通讯

时间:2015-05-25 12:18:23

标签: python unit-testing

我正在python中构建一个应用程序,它使用对执行硬件通信的库的包装

我想创建一些测试单元,我对单元测试很新,所以我想嘲笑通信,但我真的不知道怎么做

快速示例:

这是使用comm lib的应用程序代码

def changeValue(id, val):
    current_value = comm.getval(id)
    if (current_value != val):
        comm.send(id, val)

我想在不执行通信的情况下测试它,即用一些模拟值替换comm.getval返回,并将comm.send发送到模拟的comm类。

任何人都可以提示吗?

问题是comm是类中的对象

让我们说课程是这样的:

class myClass:
    comm = Comm()
    ....
    def __init__():
        comm = comm.start()

    def changeValue(id, val):
        ....

    ....

2 个答案:

答案 0 :(得分:2)

您可以将mock框架用于此类工作。首先你要用 comm = Comm()中的MyClass,这意味着您在from comm_module import Comm的模块中有MyClass之类的内容。在这些情况下,您需要修补Comm模块中的MyClass引用,以使您的补丁处于活动状态。

所以如何在不进行任何连接的情况下测试代码的示例可以是:

@patch("my_class.Comm", autospec=True)
def test_base(self, mock_comm_factory):
    mock_comm = mock_comm_factory.return_value
    MyClass()
    mock_comm.start.assert_called_with()

@patch("my_class.Comm", autospec=True)
def test_changeValue(self, mock_comm_factory):
    mock_comm = mock_comm_factory.return_value
    mock_comm.getval.return_value = 13
    MyClass().changeValue(33, 23)
    mock_comm.getval.assert_called_with(33)
    mock_comm.send.assert_called_with(33, 23)
    mock_comm.reset_mock()
    mock_comm.getval.return_value = 23
    MyClass().changeValue(33, 23)
    mock_comm.getval.assert_called_with(33)
    self.assertFalse(mock_comm.send.called)

现在我可以开始解释我的答案的所有细节,例如为什么使用autospec=Truehow to apply patch to all methods,但这意味着要重写大量mock文档和SO答案。所以我希望这已经足够作为起点。

答案 1 :(得分:1)

诀窍不是使用像comm这样的全局对象。如果可以,请将其设置为comm由调用者注入您的类或方法。那么你所做的就是在测试时传递一个模拟的comm,然后在生产中传递一个真实的模拟comm

所以你要么在你的类中引用class myClass: .... def __init__(myComm): comm = myComm; comm = comm.start() def changeValue(id, val): current_value = comm.getval(id) if (current_value != val): comm.send(id, val) .... 引用一个字段(并通过构造函数或setter方法注入它),就像这样

def changeValue(id, val, myComm):
current_value = myComm.getval(id)
if (current_value != val):
    myComm.send(id, val)

或者你在使用它的方法中将它作为一个参数,就像这样

deferred.when

使用全局任何会让嘲讽变得非常痛苦,只要你需要嘲笑某事,就试着使用Dependency Injection

这是关于DI的另一篇好文章。它在java中,但在python http://googletesting.blogspot.ca/2008/07/how-to-think-about-new-operator-with.html

中应该是相同的