[英]Testing aiohttp client with unittest.mock.patch
我用aiohttp編寫了一個簡單的HTTP客戶端,我試圖通過修補aiohttp.ClientSession
和aiohttp.ClientResponse
來測試它。 但是,似乎unittest.mock.patch
裝飾器不尊重我的異步代碼。 猜測一下,我會說它是某種名稱空間不匹配。
這是一個最小的例子:
from aiohttp import ClientSession
async def is_ok(url:str) -> bool:
async with ClientSession() as session:
async with session.request("GET", url) as response:
return (response.status == 200)
我正在使用異步裝飾器進行測試,如本答案中所述 。 所以這是我的嘗試測試:
import unittest
from unittest.mock import MagicMock, patch
from aiohttp import ClientResponse
from my.original.module import is_ok
class TestClient(unittest.TestCase):
@async_test
@patch("my.original.module.ClientSession", spec=True)
async def test_client(self, mock_client):
mock_response = MagicMock(spec=ClientResponse)
mock_response.status = 200
async def _mock_request(*args, **kwargs):
return mock_response
mock_client.request = mock_response
status = await is_ok("foo")
self.assertTrue(status)
我的is_ok
協程在__main__
使用時工作正常,但是當我運行測試時,它會給我一個錯誤,表明我的patch
調用沒有模擬session.request
函數。 (特別是它說“無法解析來自URL'foo'的主機名”,如果它沒有被模擬,它就應該這樣做 。)
我無法逃避這種行為。 我努力了:
is_ok
后導入is_ok
。 mock_client
和mock_client.__aenter__
,設置mock_client.request
到MagicMock(return_value=mock_response)
或使用mock_client().request
等 __aenter__
和__aexit__
方法編寫模擬ClientSession
,並在new
參數中使用它進行patch
。 這些似乎沒有任何區別。 如果我將斷言放入is_ok
來測試ClientSession
是MagicMock
一個實例,那么當我運行測試時這些斷言就會失敗(同樣,當代碼沒有被修補時它們也會失敗)。 這導致了我的命名空間不匹配理論:即,事件循環運行在patch
所針對的不同命名空間中。
不管怎樣,或者我做了些蠢事!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.