编写异步aiohttp和aio文件的单元测试

时间:2020-08-31 05:32:26

标签: python-asyncio aiohttp python-aiofiles

我是asyncio的新手。我正在使用aiohttp和aiofiles下载图像。如何为这两项编写单元测试。

class ImageDownloader:
    def __init__(self, folder_path: str):
        self.folder_path = folder_path

    async def async_download_image(self, image_name: str, image_url: str):
        logging.info("%s downloading is started", image_name)
        async with aiohttp.ClientSession() as session:
            async with session.get(image_url) as resp:
                if resp.status == 200:
                    logging.info(" %s downloading is finished", image_name)
                    image_saving_path = os.path.join(self.folder_path, image_name)
                    logging.info(" %s saving to directory is started", image_name)
                    file = await aiofiles.open(image_saving_path, mode='wb')
                    await file.write(await resp.read())
                    await file.close()
                    logging.info(" %s saving to directory is finished", image_name)
                else:
                    logging.exception(IMAGE_DOWNLOADER_EXCEPTION + image_name)
                    raise ImageDownloaderError(IMAGE_DOWNLOADER_EXCEPTION + image_name)

1 个答案:

答案 0 :(得分:1)

从Python 3.8开始,Text <i>here</i> has no tag <div>This is in a div</div> 可以让您方便地测试任何异步代码的写入单元测试:

unittest.IsolatedAsyncioTestCase

对于class MyFixture(unittest.IsolatedAsyncioTestCase): async def test_1(self): result = await production_code() self.assertEqual(result, 42) ,官方建议(请参阅文档"Faking request object"中的警告)运行本地服务器来测试您的客户端。老实说,我不知道为什么,因为它与模拟昂贵依赖关系的标准规则不同。无论如何,要做到这一点,您必须重新设计函数,使其接受会话对象作为参数。这样,您可以在模拟解析器的帮助下将请求重定向到本地测试服务器。

aiohttp

通过模拟会话对象本身并产生准备好的手工测试响应,可能会更容易完全绕开整个async def production_code(client_session): aync with client_session.get(...) as response: ... ... async def test_2(self): with create_mocked_session() as mock: await production_code(mock) ... 库。

我对aiohttp一无所知,但文件输入/输出也采用相同的模式。传递一个模拟的file_like。最好将所有内容保存在内存中。