coleifer / huey

a little task queue for python
https://huey.readthedocs.io/
MIT License
5.24k stars 370 forks source link

How to do mocking/monkey patching in huey tasks? #134

Closed laike9m closed 8 years ago

laike9m commented 8 years ago

I want to test a huey task, and need to patch requests.get.

# huey_tasks.py
@huey.task()
def function():
    import requests
    print(requests.get('http://www.google.com'))
import huey_tasks

@patch('requests.get')
def call_patched(fake_get):
    fake_get.return_value = '1'
    huey_tasks.function()

Launch huey_consumer: huey_tasks.huey -w 10 -l logs/huey.log Run test, however patching didn't have any effect.

[2016-01-24 17:01:12,053] INFO:requests.packages.urllib3.connectionpool:Worker-1:Starting new HTTP connection (1): www.google.com
[2016-01-24 17:01:12,562] INFO:requests.packages.urllib3.connectionpool:Worker-1:Starting new HTTP connection (1): www.google.com.sg
<Response [200]>

If I remove the @huey.task() decorator, patching works and 1 gets printed.

So how should I test huey tasks? After all, I can't remove the decorator every time, has to be a better way.

coleifer commented 8 years ago

Well, the monkey-patch needs to occur in the task instance loaded into RAM by your test. If you're running the consumer in a separate process, the patch needs to be applied there.

laike9m commented 8 years ago

@coleifer So what should I do? How do people usually test these code?

laike9m commented 8 years ago

OK, finally found a way to test

# huey_tasks.py

def _function():
    import requests
    print(requests.get('http://www.google.com'))

function = huey.task()(_function)
import huey_tasks

@patch('requests.get')
def test_patched(fake_get):
    fake_get.return_value = '1'
    huey_tasks._function()

Then directly run test code without launching huey_consumer.

coleifer commented 8 years ago

You know about always_eager, right? If not check the docs. I think that's what you are looking for. On Jan 25, 2016 12:55 AM, "Muromi Rikka" notifications@github.com wrote:

OK, finally found a way to test

huey_tasks.py

def _function(): import requests print(requests.get('http://www.google.com'))

function = huey.task()(_function)

import huey_tasks

@patch('requests.get') def call_patched(fake_get): fake_get.return_value = '1' huey_tasks._function()

Then directly run test code without launching huey_consumer.

— Reply to this email directly or view it on GitHub https://github.com/coleifer/huey/issues/134#issuecomment-174419135.

laike9m commented 8 years ago

I know there's always_eager, but you can't test a function which is already decorated with @task and monkey patch it at the same time. The above solution is the only way I can think of. My question has nothing to do with whether huey runs with Redis or not.

jedie commented 4 years ago

I have a similar problem: I use https://pypi.org/project/requests-mock/ to mock requests calls. And it works in huey immediate mode.

EDIT: It works, my mistake ;)