2016-03-01 18 views
0

如果我有两个文件包含以下内容:蟒蛇单元测试模拟不能处理的部分限定的名称

test_helper.py

class Installer: 
    def __init__(self, foo, bar, version): 
     # Init stuff 
     raise Exception('If we're here, mock didn't work') 

    def __enter__(self): 
     return self 

    def __exit__(self, type, value, tb): 
     # cleanup 
     pass 

    def install(self): 
     # Install stuff 
     raise Exception('If we're here, mock didn't work') 

而且 test.py

import unittest 
from mock import patch 
from test_helper import Installer 

class Deployer: 
    def deploy(self): 
     with Installer('foo', 'bar', 1) as installer: 
      installer.install() 

class DeployerTest(unittest.TestCase): 
    @patch('tests.test_helper.Installer', autospec=True) 
    def testInstaller(self, mock_installer): 
     deployer = Deployer() 
     deployer.deploy() 
     mock_installer.assert_called_once_with('foo', 'bar', 1) 

上面的代码没有正确测试。模拟是一个不正确应用:

File "/Library/Python/2.7/site-packages/mock-1.3.0-py2.7.egg/mock/mock.py", line 947, in assert_called_once_with 
    raise AssertionError(msg) 
AssertionError: Expected 'Installer' to be called once. Called 0 times. 

如果我做出test.py以下更改:

  1. 变化from test_helper import Installerimport test_helper,并且
  2. 变化with Installer('foo', 'bar', 1) as installer:with test_helper.Installer('foo', 'bar', 1) as installer:

代码然后工作。为什么模拟只适用于使用完全限定名称?它应该在部分合格的情况下工作吗?

回答

0

您正在测试您的Deployer课程test.py,该课程正在调用Installer。这个安装程序是你想要模拟的。所以,你的装饰者应该尊重这一点。

我不知道你从哪里测试。但是,作为一个例子,如果你是从同一水平test.py运行测试,那么你可以简单地这样对你的装饰,它应该工作:

import unittest 

from dower import Installer 
from mock import patch 

class Deployer: 
    def deploy(self): 
     with Installer('foo', 'bar', 1) as installer: 
      installer.install() 

class DeployerTest(unittest.TestCase): 
    @patch('test.Installer', autospec=True) 
    def testInstaller(self, mock_installer): 
     deployer = Deployer() 
     deployer.deploy() 
     mock_installer.assert_called_once_with('foo', 'bar', 1) 


if __name__ == '__main__': 
    unittest.main() 

注意:您不应该在安装模块内嘲讽。在这种情况下,您不需要关心安装程序护理。只是它返回您的Mock,因此您可以继续测试Deployer的行为。想想那样,你会意识到为什么你必须嘲笑你正在测试的东西。

+0

我想这是一个混合的问题。然而,这主要是与http://stackoverflow.com/questions/16060724/patch-why-wont-the-relative-patch-target-name-work这是我正在寻找。不过谢谢你的回答! – Srikanth

+1

@Srikanth深入阅读https://docs.python.org/3/library/unittest.mock.html#where-to-patch(如果需要的话,3或4次)然后接受这个答案,因为它是正确的。 –