0

distlib が pypi プロジェクトを正しく解析していないために発生する Python パッケージ caniusepython3 のバグを修正しようとしています。私はこの単体テストを書いた

 @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.

そのため、distlib の次のリリースでエラーが修正されても、テスト ケースは引き続き有効です。

問題は、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 << ---------------------

が呼び出されたときに MagicMock が例外を返さないのはなぜdistlib.locator.locate()ですか?

更新:使用に切り替えたときに、この単体テストを機能させることができました

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.

しかし、デコレータ形式で何が間違っていたのか、まだ疑問に思っています。

4

1 に答える 1

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()
    # ...
于 2015-04-17T05:26:37.237 に答える