2017-06-16 63 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