3

モック python ライブラリを使用しようとしていますが、デコレータを使用して、対応する置換メソッドでモック side_effect vars を設定するためのいくつかの繰り返し操作を非表示にすることにしました。

これまでのところ、テストに入らない次のコードがありますが、基本的には何もしません。これを修正する方法についてのアイデアはありますか? ありがとう!

import unittest
from mock import patch

# Replacement method for requests.get call
def mock_requests_get(url=None, **kwargs):
    if url == URL1:
        return {'url':url, 'status_code':200, 'status':'success'}

    if url == URL2: A
        return {'url':url, 'status_code':403}

# Replacement method for requests.post call
def mock_requests_post(url, data=None, **kwargs):
    if url == URL1 and data['data']=='go':
        return {'url':url, 'status_code':200, 'status':'success'}

    if url == URL2 and data['data']!='gogo':
        return {'url':url, 'status_code':403}

# Decorator which sets mock replacement methods
def mock_type(method=''):
    def _mock(func):
        def _decorator(mock_get, mock_post, *args, **kwargs):
            print method
            if method == 'GET':
                mock_get.side_effect = mock_requests_get
            if method == 'POST':
                mock_post.side_effect = mock_requests_post
            func(mock_get, mock_post, *args, **kwargs)
        return _decorator
    return _mock

@patch('requests.post')
@patch('requests.get')
class TestKeywordsApi(unittest.TestCase):

    def setUp(self):
        self.ka = KeywordsApi()

    @mock_type('GET')
    def test_get(self, mock_get, mock_post):
        # Replace this code in mock_type decorator:
        #mock_get.side_effect=mock_requests_get

        print self.ka.get(URL1)
        print self.ka.get(URL2)

        # Do asserts

    @mock_type('POST')
    def test_post(self, mock_get, mock_post):
        # Replace this code in mock_type decorator:
        #mock_post.side_effect=mock_requests_post

        print self.ka.post(URL1, {'data':'go'})
        print self.ka.post(URL2, {'data':'go'})

        # Do asserts
4

1 に答える 1

2

実行名前空間の関数を必ず置き換えてください。インポートに応じて、現在のコードは、置き換えていると思われるものを置き換えている場合と置き換えていない場合があります。以下は、あなたがやろうとしていたと私が信じていることです。

import kwmodule
import unittest, mock

def mock_requests_get(url=None, **kwargs):
    "Replacement method for requests.get call"
    pass

def mock_requests_post(url, data=None, **kwargs):
    "Replacement method for requests.post call"
    pass

@mock.patch('kwmodule.requests.post', mock_requests_post)
@mock.patch('kwmodule.requests.get', mock_requests_get)    
class TestKeywordsApi(unittest.TestCase):
     def setUp(self):
         self.ka = kwmodule.KeywordsApi()

ただし、get と post を自動指定された MagicMock オブジェクトに置き換えると、よりうまくいく可能性があります。それがうまくいかない場合は、独自のカスタム交換を使用してください。

たとえば、次のパッチ デコレータは、「get」の呼び出し順序がわかっている場合に機能します。

return_values = [{'url':url, 'status_code':200, 'status':'success'}, 
                 {'url':url, 'status_code':403}, 
                 AssertionError('Unexpected call.')]

@mock.patch('kwmodule.requests.get', autospec=True, side_effect=return_values)

これは、最初に呼び出されたときに「成功」​​状態を返し、2 回目にはエラーを返し、3 回目に呼び出された場合は AssertionError を発生させます。10 回中 9 回は、独自のリターン生成関数を作成する代わりに、side_effect を使用しています。

于 2012-12-15T23:50:46.603 に答える