代码之家  ›  专栏  ›  技术社区  ›  Alex

模拟补丁方法和一个属性

  •  1
  • Alex  · 技术社区  · 12 年前

    我想修补一个方法返回的数据的一个属性。

    假设我有以下简化的工件代码:

    @patch('requests.post')
    class TestKeywordsApi(BaseTest):
        # Instantiate API class and set the apikey
        def setUp(self):
            BaseTest.setUp(self)
            self.fixtures = FIXTURES
            self.api = BaseApi()
    
        def mock_requests_post(self, url, data=None):
            ''' Mock method for post method from responses library.
                It replaces the responses.post calls in Api class.
            '''
            url = self.encode_url(url, data)
            if url:
                return self.fixtures[url]
    
        def test_save_success(self, mock_post):
            mock_post.side_effect = self.mock_requests_post
    
            response = self.api.post(keyword, params={...})
    
            # list of asserts
    
    # original class calling requests.post    
    import requests
    class BaseApi(object):
        def post(self, action, params):
            ''' Sends a POST request to API '''
            response = requests.post(self.build_url(action), data=params).content
    

    上面的代码失败了,因为mock方法没有为请求库中存在的“content”属性提供mock/stub。有人知道如何截断内容属性吗?

    2 回复  |  直到 12 年前
        1
  •  0
  •   hwjp    12 年前

    您的mocked post函数需要返回一个更像 requests 的响应对象,一个具有 .content 属性例如:

    from mock import Mock, patch
    #[...]
    def mock_requests_post(self, url, data=None):
        ''' Mock method for post method from responses library.
            It replaces the responses.post calls in Api class.
        '''
        mock_response = Mock()
        mock_response.content = 'my test response content'
        url = self.encode_url(url, data)
        if url:
            mock_response.url_called = self.fixtures[url]
        return mock_response
    
        2
  •  0
  •   Alex    12 年前

    我找到了以下解决方案,它只修改mock_requests_post方法,添加了一个具有我需要的属性的内部类:

    def mock_requests_post(self, url, data=None):
        ''' Mock method for post method from responses library.
            It replaces the responses.post calls in Api class.
        '''
        url = self.encode_url(url, data)
    
        class classWithAttributes(object):
            content = json.dumps(self.fixtures[url])
    
        if url:
            return classWithAttributes()