简体   繁体   中英

Unit testing Python Azure Function: How do I construct a mock test request message with a JSON payload?

I want to unit test my Python Azure function. I'm following the Microsoft documentation .

The documentation mocks the call to the function as follows

req = func.HttpRequest(
            method='GET',
            body=None,
            url='/api/HttpTrigger',
            params={'name': 'Test'})

I would like to do this but with the parameters passed as a JSON object so that I can follow the req_body = req.get_json() branch of the function code.I guessed I would be able to do this with a function call like

req = func.HttpRequest(
            method='GET',
            body=json.dumps({'name': 'Test'}),
            url='/api/HttpTrigger',
            params=None)

If I construct the call like this, req.get_json() fails with the error message AttributeError: 'str' object has no attribute 'decode' .

How do I construct the request with JSON input parameters? It should be trivial but I'm clearly missing something obvious.

If I construct my mock call as follows:

import json


req = func.HttpRequest(
            method='POST',
            body=json.dumps({'name': 'Test'}).encode('utf8'),
            url='/api/HttpTrigger',
            params=None)

Then I am able to make a successful call to req.get_json() . Thanks to @MrBeanBremen and @JoeyCai for pointing me in the correct direction ie don't call GET and make the message a byte string.

Any HTTP request message is allowed to contain a message body, and thus must parse messages with that in mind. Server semantics for GET, however, are restricted such that a body, if any, has no semantic meaning to the request. The requirements on parsing are separate from the requirements on method semantics.

For your http request, it is a GET method. You can send a request body with GET but it should not have any meaning.

So use the below code to construct a mock HTTP request with a json payload. For more details, you could refer to this article .

req = func.HttpRequest(
    method='GET',
    body=None,
    url='/api/HttpTrigger',
    params={'name': 'Test'})

Update:

For Post request, you could send json payload with body=json.dumps({'name': 'Test'}).encode('utf8') while body expects a byte string :

req = func.HttpRequest(
    method='POST',
    body=json.dumps({'name': 'Test'}).encode('utf8'),
    url='/api/HttpTrigger',
    params=None)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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