简体   繁体   English

如何在python中模拟.patch一个普通字典?

[英]How to mock.patch a plain dictionary in python?

How do I mock.patch a plain dictionary {} ?我如何 mock.patch 一个普通的字典 {} ?

I would like to check if the headers is set to {'Content-Type': 'application/json'}.我想检查标题是否设置为 {'Content-Type': 'application/json'}。

def get(self):
    result = Spider.get_news_urls()
    for k, v in result.iteritems():
        response = requests.get(v)
        xml = response.text()
        headers = {'Content-Type': 'application/json'}
        data = ''
        taskqueue.Task(url='/v1/worker', headers=headers, payload=json.dumps(data)).add(queue_name='itagnewstasks')
    return 'success', 200

The following unit test seems to successfully patch dict.以下单元测试似乎成功地修补了 dict。 But I have a {}, which I need to patch.但我有一个 {},我需要修补它。

@mock.patch('__builtin__.dict')
@mock.patch('requests.get')
def test_header_is_set_to_json(self, req_get, x):
    gen = Generator()
    gen.get()
    x.assert_called_with()

I suppose an alternative way would be to mock patch taskqueue.Task() and compare if it was called with headers= {'Content-Type': 'application/json'} as a parameter.我想另一种方法是模拟补丁taskqueue.Task()并比较是否使用headers= {'Content-Type': 'application/json'}作为参数调用它。

The headers you seek to mock are constructed within the method you are testing, so mocking the taskqueue.Task call would be much easier.您要模拟的标头是在您正在测试的方法中构造的,因此模拟taskqueue.Task调用会容易得多。 If you were passing the header dict into the method then you could just hold onto a copy and check that it has been updated as you expect.如果您将标题 dict 传递到方法中,那么您可以保留一个副本并检查它是否已按您的预期更新。

You can usepatch.dict to mock a dictionary:您可以使用patch.dict来模拟字典:

>>> foo = {}
>>> with patch.dict(foo, {'newkey': 'newvalue'}):
...     assert foo == {'newkey': 'newvalue'}
...
>>> assert foo == {}

Ran in to an issue with patch.dict today.今天遇到了patch.dict的问题。

patch.dict rolls back the whole dict at __exit__ ... not just the patched values. patch.dict__exit__回滚整个 dict ... 而不仅仅是修补的值。 if this isn't the behavior you want, you might want to use a patcher that's more selective.如果这不是您想要的行为,您可能需要使用更具选择性的修补程序。

This works the same as patch.dict , but it only restores the keys you patched.这与patch.dict工作方式相同,但它仅恢复您修补的密钥。

class DictPatch:
    def __init__(self, obj, patch):
        self.obj = obj
        self.patch = patch
        self.save = {}
        self.pop = []

    def start(self):
        self.save = {k: v for k, v in self.obj.items() if k in self.patch}
        self.pop = [k for k in self.patch if k not in self.obj]
        self.obj.update(self.patch)
        # this allows you to do self.addCleanup(DictPatch(...)), which is nice
        return self.stop

    def stop(self):
        self.obj.update(self.save)
        for k in self.pop:
            self.obj.pop(k)

    def __enter__(self):
        self.start()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.stop()

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

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