简体   繁体   English

如何使用python模拟库和decorator与unittest lib?

[英]How to use python mock library and decorator with unittest lib?

I am trying to use mock python library, and decided to use a decorator to hide a few repetitive operations for setting mock side_effect vars with corresponding replacement methods. 我正在尝试使用模拟python库,并决定使用装饰器来隐藏一些重复操作,以便使用相应的替换方法设置模拟side_effect变量。

So far I have the following code, which does not enter the tests, it basically does nothing. 到目前为止,我有以下代码,它没有进入测试,它基本上什么也没做。 Any ideas on how to fix this? 有想法该怎么解决这个吗? Thanks! 谢谢!

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

Make sure to replace the functions in the execution namespace. 确保替换执行命名空间中的函数。 Depending on the imports, your current code may or may not be replacing what you think it is replacing. 根据导入,您当前的代码可能会或可能不会替换您认为它正在替换的内容。 The following does what I believe you were trying to do. 以下是我认为您试图做的事情。

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()

However, you may be more successful with replacing get & post with autospecced MagicMock objects. 但是,使用自动指定的MagicMock对象替换get&post可能会更成功。 If that doesn't work for you, then use your own custom replacement. 如果不为你工作, 然后使用自己的自定义更换。

For instance, the following patch decorator would work if you know the order of calls to "get." 例如,如果您知道“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)

This will return a "success" condition the first time it is called, an error the second time, and it will raise an AssertionError if it is called a third time. 这将在第一次调用时返回“成功”条件,第二次返回错误,如果第三次调用它将引发AssertionError。 Nine times out of ten, I use side_effect instead of writing my own return generating function. 十分之九,我使用side_effect而不是编写自己的返回生成函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM