2017-06-16 29 views
1

我有以下配置類:懲戒屬性調用返回MagicMock,不珍惜

class ConfigB(object): 
    Id = None 

    def __Init__(self, Id): 
    self.Id = Id 

這是在下面的類實例化,以及屬性印刷:

from config.ConfigB import ConfigB 

class FileRunner(object): 
    def runProcess(self, Id) 
    cfgB = ConfigB(Id) 
    print(cfgB.Id) 

我已經創建瞭如下測試類來測試它,其中我試圖模擬實例化和cfgB.Id屬性調用:

import unittest 
import unittest.mock imort MagicMock 
import mock 
from FileRunner import FileRunner 

class TestFileRunner(unittest.TestCase): 
    @mock.patch('ConfigB.ConfigB.__init__') 
    @mock.patch('ConfigB.ConfigB.Id') 
    def test_methodscalled(self, cfgBId, cfgBInit): 


    fileRunner = FileRunner() 

    cfgBId.return_value = 17 

    cfgBInit.return_value = None 

    print(cfgBId) 

    fileRunner.runProcess(1) 

注fileRunner之前打印(cfgBId)語句被調用。我得到以下輸出:

<MagicMock name='Id' id='157297352'> 
<MagicMock name='Id' id='157297352'> 

出於某種原因,當我在測試類此處設置的返回值:

cfgBId.return_value = 17 

,在FileRunner是沒有得到所謂的上線()類:

print(cfgB.Id) 

我需要做些什麼才能正確顯示我的配置屬性?

還要注意的是我的「ConfigB」類的實例要複雜得多,高於該比顯示就是爲什麼我要修補的實例化和調用ID屬性。

*更新:我已經改變了我的課由@mgilson的建議,但它仍然不工作:

import unittest 
import unittest.mock imort MagicMock 
import mock 
from FileRunner import FileRunner 

class TestFileRunner(unittest.TestCase): 
    @mock.patch('FileRunner.ConfigB') 
    def test_methodscalled(self, cfgB): 

    fileRunner = FileRunner() 

    cfgB.Id = 17 

    print(cfgBId) 

    fileRunner.runProcess(1) 

我現在正從兩個print語句的輸出如下:

<MagicMock name='ConfigB' id='157793640'> 
<MagicMock name='ConfigB().Id' id='157020512'> 

任何想法,爲什麼上面不工作?

*解決方案:

我能得到它的一個小的改動,以測試方法@mgilson建議後工作:

import unittest 
import unittest.mock imort MagicMock 
import mock 
from FileRunner import FileRunner 

class TestFileRunner(unittest.TestCase): 
    @mock.patch('FileRunner.ConfigB') 
    def test_methodscalled(self, cfgB): 

    fileRunner = FileRunner() 

    cfgB().Id = 17 

    print(cfgBId) 

    fileRunner.runProcess(1) 

我現在得到以下的輸出:

<MagicMock name='ConfigB' id='157147936'> 
17 

回答

1

它看起來對我來說,這將是最好只更換整個ConfigB對象在FileRunner命名空間。然後你的測試看起來是這樣的:

import unittest 
import unittest.mock imort MagicMock 
import mock 
from FileRunner import FileRunner 

class TestFileRunner(unittest.TestCase): 
    @mock.patch('FileRunner.ConfigB') 
    def test_methodscalled(self, cfgB): 
    fileRunner = FileRunner() 
    cfgB.return_value.Id = 17 
    fileRunner.runProcess(1) 

注意@mock.patch('FileRunner.ConfigB')是要替換FileRunner命名空間中使用模擬的ConfigB類。然後,您可以配置模擬以進行任何您喜歡的操作 - 例如有一個Id,等於17

+0

所以我試圖實現(見我的帖子上的編輯),但我仍然沒有得到正確的輸出。 – EliSquared

+0

Acutally @mgilson我能夠讓它工作我想我只是將代碼中的行從'cfgB.Id = 17'更改爲'cfgB()。Id = 17'。括號改變了一切。這對你有意義嗎?如果您編輯您的帖子以包含括號,我可以將其標記爲解決方案。 – EliSquared

+1

@EliSquared - 是的,這很有道理。你想把'Id'附加到你的模擬的'return_value',而不是模擬本身(我的壞)。我編輯了代碼來反映這一點。 – mgilson

0

爲了模擬Id屬性,你可以用一個Mock實例化屬性來修補類,如下所示:

@mock.patch('ConfigB.ConfigB', Mock(Id='17')) 
def test_methodscalled(self, cfgB): 
    cfgB.return_value.__init__.return_value = None # FWIW, this isn't necessary 
+0

所以我不能讓你的建議的工作,但我沒有找到與@mgilson的幫助下解決方案。看到我最後的更新。 – EliSquared