2015-04-17 75 views
0

I'm attempting to fix a bug in the python package caniusepython3 which arises because distlib isn't parsing pypi projects correctly.我寫這個單元測試@ mock.patch甚至設置side_effect

@mock.patch('distlib.locators.locate') 
def test_blocking_dependencies_locators_fails(self, distlib_mock): 
    """ 
    Testing the work around for //bitbucket.org/pypa/distlib/issue/59/ 
    """ 
    py3 = {'py3_project': ''} 
    breaking_project = 'test_project' 
    distlib_mock.locators.locate.return_value = "foo" 
    distlib_mock.locators.locate.side_effect = AttributeError() 
    got = dependencies.blocking_dependencies([breaking_project], py3) 
    # If you'd like to test that a message is logged we can use 
    # testfixtures.LogCapture or stdout redirects. 
後不加屬性錯誤

So that when distlib fixes the error in the next release of distlib the test case will still be valid.

的問題是,MagicMock從未提出了一個AttributeError的我預期並返回魔術模擬對象的字符串表示形式

try: 
    # sets dist to <MagicMock name='locate()' id='4447530792'> 
    dist = distlib.locators.locate(project) 
except AttributeError: 
    # This is a work around //bitbucket.org/pypa/distlib/issue/59/ 
    log.warning('{0} found but had to be skipped.'.format(project)) 
    continue 

並且因爲它返回對象而導致此堆棧跟蹤repr,

====================================================================== 
ERROR: Testing the work around for //bitbucket.org/pypa/distlib/issue/59/ 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/unittest/mock.py", line 1136, in patched 
    return func(*args, **keywargs) 
    File "/Users/alexlord/git/caniusepython3/caniusepython3/test/test_dependencies.py", line 81, in test_blocking_dependencies_locators_fails 
    got = dependencies.blocking_dependencies([breaking_project], py3) 
    File "/Users/alexlord/git/caniusepython3/caniusepython3/dependencies.py", line 119, in blocking_dependencies 
    return reasons_to_paths(reasons) 
    File "/Users/alexlord/git/caniusepython3/caniusepython3/dependencies.py", line 43, in reasons_to_paths 
    parent = reasons[blocker] 
    File "/Users/alexlord/git/caniusepython3/caniusepython3/dependencies.py", line 29, in __getitem__ 
    return super(LowerDict, self).__getitem__(key.lower()) 
nose.proxy.KeyError: <MagicMock name='locate().name.lower().lower()' id='4345929400'> 
-------------------- >> begin captured logging << -------------------- 
ciu: INFO: Checking top-level project: test_project ... 
ciu: INFO: Locating <MagicMock name='locate().name.lower()' id='4344734944'> 
ciu: INFO: Dependencies of <MagicMock name='locate().name.lower()' id='4344734944'>: [] 
--------------------- >> end captured logging << --------------------- 

爲什麼在調用distlib.locator.locate()時MagicMock不會返回異常?

更新:我能得到這個單元測試在工作的時候切換到使用

def test_blocking_dependencies_locators_fails(self): 
    """ 
    Testing the work around for //bitbucket.org/pypa/distlib/issue/59/ 
    """ 
    with mock.patch.object(distlib.locators, 'locate') as locate_mock: 
     py3 = {'py3_project': ''} 
     breaking_project = 'test_project' 
     locate_mock.side_effect = AttributeError() 
     got = dependencies.blocking_dependencies([breaking_project], py3) 
     # If you'd like to test that a message is logged we can use 
     # testfixtures.LogCapture or stdout redirects. 

但我仍然不知道我做錯了什麼與裝飾格式。

+1

怎麼了所有的美元符號? – user2357112

+0

來自vim的額外字符。 – AlexLordThorsen

回答

2

當您使用@mock.patch時,它會嘲笑您告訴它,並將該模擬對象作爲參數傳遞。因此,您的distlib_mock參數模擬locate函數。您正在有效地設置distlib.locators.locate.locators.locate上的屬性。直接在提供的模擬上設置屬性,事情應該更好。

@mock.patch('distlib.locators.locate') 
def test_blocking_dependencies_locators_fails(self, locate_mock): 
    # ... 
    locate_mock.return_value = "foo" 
    locate_mock.side_effect = AttributeError() 
    # ... 
相關問題