2016-03-01 47 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次)然後接受這個答案,因爲它是正確的。 –