简体   繁体   中英

How To Fix Error For Test of Azure Function (Python) With Http Trigger and Queue Message Output

I am getting the following error when I run a test on a python Azure Function:

obj = super().__new__(cls, *args, **kwds)
TypeError: object.__new__() takes exactly one argument (the type to instantiate)

I am getting the error when the function calls msg.set() as the value I am passing in from the test is not correct.

This is the function I am testing:

import logging    
import azure.functions as func
    
def main(req: func.HttpRequest, msg: func.Out[func.QueueMessage]) -> func.HttpResponse:
    
    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        msg.set(name)
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
             "Please pass a name on the query string or in the request body",
             status_code=400
        )

And here is the test code:

# test_some.py
import unittest
import azure.functions as func

from . import main

class Test_Some(unittest.TestCase):
    def test_my_function_for_no_name(self):
        testVal = 'Some Guy'
        # Construct a mock HTTP request.
        req = func.HttpRequest(
            method='GET',
            body=None,
            url='/api/HttpExample',
            params={'name': testVal})

        queue_msg = func.QueueMessage(body=b'')

        msg = func.Out(queue_msg)

        # Call the function.
        resp = main(req, msg)

        # Check the output.
        self.assertEqual(
            resp.get_body(),
            b'Hello Some Guy!',
        )

if __name__ == '__main__': unittest.main()

The test code should be:

# HttpTrigger1/test_queryurls.py
from . import main
import unittest
import logging
import azure.functions as func

class Test_Some(unittest.TestCase):
    def test_my_function_for_no_name(self):
        testVal = 'Some Guy'
        # Construct a mock HTTP request.
        req = func.HttpRequest(
            method='GET',
            body=None,
            url='/api/HttpExample',
            params={'name': testVal})

        queue_msg = func.QueueMessage(body=b'')
        queue_msg.__setattr__('set', set)

        resp = main(req, queue_msg)

        # Check the output.
        self.assertEqual(
            resp.get_body(),
            b'Hello Some Guy!',
        )

    def set(inStr:str):
        logging.info(inStr)

if __name__ == '__main__': unittest.main()

The problem was how to compose the second object to pass from the unittest to the function. The function signature of the second object is msg: func.Out[func.QueueMessage]. func.Out is an abstract class so cannot be instantiated. func.QueueMessage can be instantiated but does not have a set method on it so cannot be used as is. Therefore I created a func.QueueMessage object and added a blank set method to the object using setsttr . I might amend the new "set" method if I need it to do more.

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