你的单元测试的代码(也许在其setUp
方法中,如果这是需要在几个试验方法和由此有资格作为夹具)应该做的:
def fake_command(cls, host, cmd, sh=None):
pass # whatever you want in here
self.save_remote_command = somemodule.RemoteCommand.remote_command
somemodule.RemoteCommand.remote_command = classmethod(fake_command)
,然后撤消此猴修补(例如在)由
somemodule.RemoteCommand.remote_command = self.save_remote_command
的tearDown
方法,如果修补在setUp
做这并不总是必要的测试后,把东西回来,但它是很好的一般做法。
一个更优雅的方法是通过依赖注入来设计您的可测试性的代码(DI)模式:
def __init__(self, ...):
...
self.remote_command = RemoteCommand.remote_command
...
def set_remote_command_function(self, thefunction):
self.remote_command = thefunction
def get_interface_params_by_mac(self, host, mac_unified):
lines = self.remote_command(host, cls.IFCONFIG)
DI买你一个很大的灵活性(可测试性,明智的,而且在许多其他情况下),这使得它成为我最喜欢的设计模式之一(我宁愿尽可能避免使用猴子修补)。当然,如果你在测试中设计你的代码来使用DI,那么在你的测试中你需要做的所有事情都是通过调用实例的set_remote_command_function
以及你想使用的任何假函数来准备好这个实例。
谢谢,亚历克斯。这正是我需要的。我还想读一些关于DI的东西。你能给我一个链接吗? – legesh 2009-11-05 20:15:25
另一个问题...我真的需要一个方法set_remote_command_function?据我所知,我可以写这样的东西:myobj.remote_command = RemoteCommand.remote_command – legesh 2009-11-05 20:40:40
@legesh,对于DI,见http://www.aleax.it/yt_pydi.pdf我的演示文稿的PDF。不,你不一定需要一个setter方法,直接的属性分配(如果你需要在这样的任务上做一些记录,可能通过一个属性)也可以工作。 – 2009-11-06 04:24:18