[英]What's wrong with this Python mock patch?
我在單元測試中無法模擬導入的模塊。 我正在嘗試使用模擬模塊模擬我的模塊tracker.models
的 PIL Image 類。 我知道你應該在使用它們的地方模擬它們,所以我寫了@mock.patch('tracker.models.Image')
作為我的單元測試裝飾器。 我正在嘗試檢查下載的圖像是否作為 PIL 圖像打開。 模擬補丁似乎覆蓋了整個 Image 模塊。 這是我運行測試時遇到的錯誤:
File "/home/ubuntu/workspace/tracker/models.py", line 40, in set_photo
width, height = image.size
ValueError: need more than 0 values to unpack
這是我的單元測試:
測試模型.py
@responses.activate
@mock.patch('tracker.models.Image')
def test_set_photo(self, mock_pil_image):
# Initialize data
hammer = Product.objects.get(name="Hammer")
fake_url = 'http://www.example.com/prod.jpeg'
fake_destination = 'Hammer.jpeg'
# Mock successful image download using sample image. (This works fine)
with open('tracker/tests/test_data/small_pic.jpeg', 'r') as pic:
sample_pic_content = pic.read()
responses.add(responses.GET, fake_url, body=sample_pic_content, status=200, content_type='image/jpeg')
# Run the actual method
hammer.set_photo(fake_url, fake_destination)
# Check that it was opened as a PIL Image
self.assertTrue(mock_pil_image.open.called,
"Failed to open the downloaded file as a PIL image.")
這是它正在測試的一段代碼。
跟蹤器/models.py
class Product(models.Model):
def set_photo(self, url, filename):
image_request_result = requests.get(url)
image_request_result.content
image = Image.open(StringIO(image_request_result.content))
# Shrink photo if needed
width, height = image.size # Unit test fails here
max_size = [MAX_IMAGE_SIZE, MAX_IMAGE_SIZE]
if width > MAX_IMAGE_SIZE or height > MAX_IMAGE_SIZE:
image.thumbnail(max_size)
image_io = StringIO()
image.save(image_io, format='JPEG')
self.photo.save(filename, ContentFile(image_io.getvalue()))
您需要配置Image.open
的返回值以包含size
屬性:
opened_image = mock_pil_image.open.return_value
opened_image.size = (42, 83)
現在,當您的被測函數調用Image.open
,返回的MagicMock
實例將具有一個元組的size
屬性。
您可以對需要返回某些內容的任何其他方法或屬性執行相同的操作。
opened_image
參考也可用於測試被測函數的其他方面; 您現在可以斷言image.thumbnail
和image.save
被調用:
opened_image = mock_pil_image.open.return_value
opened_image.size = (42, 83)
# Run the actual method
hammer.set_photo(fake_url, fake_destination)
# Check that it was opened as a PIL Image
self.assertTrue(mock_pil_image.open.called,
"Failed to open the downloaded file as a PIL image.")
self.assertTrue(opened_image.thumbnail.called)
self.assertTrue(opened_image.save.called)
這使您可以非常准確地測試縮略圖大小邏輯是否正常工作,例如,無需測試 PIL 是否在做它所做的; 畢竟,這里沒有測試 PIL。
我正在編寫一個類似的測試,但我的函數使用Image.open
作為上下文管理器( with Image.open(<filepath>) as img:
)。 感謝的Martijn Pieters的的答案,這一次我能我的測試獲得與工作:
mock_pil_image.open.return_value.__enter__.return_value.size = (42, 83)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.