0

我编写了一个函数,它基本上隐藏了使用 pySnmp 库发送 SNMP 消息的复杂性,它看起来像:

snmpWalk(host,oid):
    from pysnmp.entity.rfc3413.oneliner import cmdgen
    cg = cmdgen.CommandGenerator()
    comm_data = cmdgen.CommunityData('my-manager','public')
    transport = cmdgen.UdpTransportTarget((host,161))
    variables = oid
    return cg.nextCmd(comm_data,transport,variables)

我是单元测试的新手,我试图为此代码编写一个单元测试作为使用 minimock 的 doctest,这就是我想出的:

#Setup the mocks
>>> from minimock import mock, Mock
>>> cmdgen.CommandGenerator = Mock('cmdgen.CommandGenerator')
>>> cmdgen.CommunityData = Mock('cmdgen.CommunityData')
>>> cmdgen.UdpTransportTarget = Mock('cmdgen.UdpTransportTarget')
>>> cgMock = Mock('cgMock')
>>> cmdgen.CommandGenerator.mock_returns = cgMock
>>> cmdgen.CommunityData.mock_returns = 1
>>> cmdgen.UdpTransportTarget.mock_returns = 2
>>> cgMock.nextCmd.mock_returns = (1,2,3,4)
#run the test
>>> PrinterMonitor.SnmpWalk('192.0.0.1','1.1.1.1.1.1.1') 
Called cmdgen.CommandGenerator()
Called cmdgen.CommunityData('my-manager', 'public')
Called cmdgen.UdpTransportTarget(('192.0.0.1', 161))
Called cgMock.nextCmd(1, 2, (1, 1, 1, 1, 1, 1, 1))
(1, 2, 3, 4)

所以我运行了这个测试,结果很好,但我的问题是,我真的需要付出所有这些努力来模拟 3rd 方库的各个方面吗?在我看来,我需要模拟的最低限度是最后一行cg.nextCmd(comm_data,transport,variables),因为我实际上并不想在我的单元测试中开始向打印机发送消息,但是对库代码的其他调用应该会给我一致的结果,具体取决于什么我传给他们。我可以确保我的代码与库进行适当的交互(即,通过在传递给模拟cg.nextCmd(...)调用的对象上断言 this 来确保它正确地将主机参数传递给传输变量?

4

1 回答 1

0

你需要经历所有这些努力吗?不。

要测试使用您的snmpWalk()函数的代码,您最好模拟出包含该函数的类。我不知道 Python 术语,但在 Java 术语中,我会放入snmpWalk()一个接口,然后有一个 pySnmp 实现和任意数量的模拟/测试实现。代码调用snmpWalk()不应该关心任何内部细节,它只关心返回值,所以这就是你想要模拟的级别。

要测试 pySnmp 实现类本身,您可以模拟库调用,但这需要大量工作并且有风险,因为您的模拟必须非常接近地模拟库。我会坚持真正的电话。如果这意味着触发真正的打印机请求,请不要经常运行该测试——或者看看是否有办法将库配置为打印到虚拟/假打印机。

于 2012-01-24T18:24:34.267 回答