我在单元测试中嘲笑导入的模块时遇到了麻烦。我试图使用mock模块在我的模块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
这是我的单元测试:
test_models.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()))
答案 0 :(得分:6)
您需要配置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没有在这里进行测试。
答案 1 :(得分:0)
我正在编写类似的测试,但是我的功能是使用using namespace std
作为上下文管理器(Image.open
)。多亏Martijn Pieters的回答和this one,我才得以将测试用于:
with Image.open(<filepath>) as img: