Python Coding Academy
135 subscribers
7 photos
3 files
4 links
🐍 Learn Python. Build Skills. Create the Future.

📚 Python lessons from beginner to advanced
💻 Clear explanations & real-world examples
🚀 Learn to code. Learn to build.
Download Telegram
🐍 آموزش Python | پست ۲۶۳
بررسی تعداد فراخوانی‌های Mock
در تست‌نویسی، گاهی لازم است علاوه بر بررسی خروجی، تعداد دفعات اجرای یک تابع یا متد را نیز کنترل کنیم.
کتابخانه unittest.mock چند ابزار برای این کار ارائه می‌دهد.
۱. ویژگی call_count
این ویژگی تعداد دفعات فراخوانی یک Mock را مشخص می‌کند:
from unittest.mock import Mock

send_email = Mock()

send_email()
send_email()
send_email()

print(send_email.call_count)

خروجی:
3

۲. متد assert_called_once()
بررسی می‌کند که Mock دقیقاً یک‌بار فراخوانی شده باشد:
send_email = Mock()

send_email()

send_email.assert_called_once()

اگر Mock صفر بار یا بیشتر از یک بار فراخوانی شده باشد، تست با AssertionError شکست می‌خورد.
۳. متد assert_not_called()
بررسی می‌کند که Mock اصلاً فراخوانی نشده باشد:
send_email = Mock()

send_email.assert_not_called()

اگر حتی یک‌بار فراخوانی شده باشد، این بررسی شکست می‌خورد.
۴. متد assert_called()
بررسی می‌کند که Mock حداقل یک‌بار فراخوانی شده باشد:
send_email = Mock()

send_email()

send_email.assert_called()

۵. بررسی تعداد فراخوانی در یک تست واقعی
import unittest
from unittest.mock import Mock

class TestNotification(unittest.TestCase):

def test_send_notification(self):
notify = Mock()

notify("User 1")
notify("User 2")

self.assertEqual(notify.call_count, 2)
notify.assert_called()

self.assertEqual(
notify.call_args_list[0].args,
("User 1",)
)


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

در این تست:
تعداد فراخوانی‌ها باید دقیقاً ۲ باشد.
Mock حداقل یک‌بار اجرا شده باشد.
اولین فراخوانی باید آرگومان "User 1" را دریافت کرده باشد.
نکته مهم
تفاوت این ابزارها:
ابزار
کاربرد
call_count
دریافت تعداد فراخوانی‌ها
assert_called()
حداقل یک فراخوانی
assert_called_once()
دقیقاً یک فراخوانی
assert_not_called()
بدون هیچ فراخوانی
🎯 تمرین
یک Mock به نام save_data بسازید و آن را چهار بار فراخوانی کنید.
سپس با استفاده از call_count و assert_called() تعداد و وضعیت فراخوانی‌ها را بررسی کنید.
پست ۲۶۳ از دوره جامع Python 🐍
👍1
🐍 آموزش Python | پست ۲۶۴
بازنشانی Mock با reset_mock()
در تست‌نویسی ممکن است بخواهیم یک Mock را چند بار استفاده کنیم، اما اطلاعات مربوط به فراخوانی‌های قبلی آن روی تست جدید تأثیر نگذارد.
برای این کار از متد reset_mock() استفاده می‌کنیم.
۱. پاک‌کردن تاریخچه فراخوانی‌ها
from unittest.mock import Mock

api = Mock()

api("Hello")
api("Python")

print(api.call_count)

api.reset_mock()

print(api.call_count)

خروجی:
2
0

با اجرای reset_mock() اطلاعات مربوط به فراخوانی‌های قبلی پاک می‌شوند.
۲. بررسی تاریخچه پس از Reset
from unittest.mock import Mock

api = Mock()

api(10)
api(20)

api.reset_mock()

print(api.call_args)
print(api.call_args_list)
print(api.call_count)

خروجی:
None
[]
0

۳. آیا reset_mock() مقدار return_value را هم پاک می‌کند؟
به‌صورت پیش‌فرض خیر.
from unittest.mock import Mock

api = Mock(return_value="Success")

api()
api.reset_mock()

print(api())

خروجی:
Success

اگر بخواهیم مقدار بازگشتی نیز بازنشانی شود، باید از پارامتر return_value=True استفاده کنیم:
api.reset_mock(return_value=True)

همچنین با side_effect=True می‌توان رفتار تعیین‌شده در side_effect را پاک کرد:
api.reset_mock(side_effect=True)

۴. بازنشانی Mockهای فرزند
اگر Mock دارای Mockهای فرزند باشد، reset_mock() به‌صورت پیش‌فرض تاریخچه آن‌ها را نیز بازنشانی می‌کند.
from unittest.mock import Mock

service = Mock()

service.database.save()
service.database.delete()

service.reset_mock()

print(service.mock_calls)

خروجی:
[]

نکات مهم
reset_mock() تاریخچه فراخوانی‌ها را پاک می‌کند.
به‌صورت پیش‌فرض return_value و side_effect حفظ می‌شوند.
با return_value=True مقدار بازگشتی بازنشانی می‌شود.
با side_effect=True رفتار جانبی پاک می‌شود.
این متد معمولاً برای استفاده مجدد از Mock در چند مرحله تست کاربرد دارد.
🎯 تمرین
یک Mock با return_value=100 بسازید.
آن را سه بار فراخوانی کنید، سپس با reset_mock() تاریخچه را پاک کنید و بررسی کنید:
مقدار call_count صفر شده باشد.
تاریخچه call_args_list خالی باشد.
مقدار return_value همچنان ۱۰۰ باقی مانده باشد.
پست ۲۶۴ از دوره جامع Python 🐍
👍1
🐍 آموزش Python | پست ۲۶۵
استفاده از PropertyMock برای تست Propertyها
در پایتون می‌توانیم با استفاده از @property، متدها را مانند ویژگی‌های معمولی فراخوانی کنیم.
اما هنگام تست چنین ویژگی‌هایی، گاهی لازم است مقدار آن‌ها را بدون اجرای منطق اصلی کنترل کنیم.
برای این کار از PropertyMock در کتابخانه unittest.mock استفاده می‌کنیم.
۱. یک کلاس با Property
class Product:
@property
def price(self):
return 500

استفاده از این ویژگی:
product = Product()

print(product.price)

خروجی:
500

۲. جایگزینی Property با PropertyMock
from unittest.mock import PropertyMock, patch

class Product:
@property
def price(self):
return 500


product = Product()

with patch.object(
Product,
"price",
new_callable=PropertyMock
) as mock_price:

mock_price.return_value = 1000

print(product.price)

خروجی:
1000

در این مثال، مقدار Property به‌صورت موقت تغییر کرده است؛ بدون اینکه کد اصلی آن اجرا شود.
۳. بررسی تعداد دسترسی به Property
با PropertyMock می‌توانیم بررسی کنیم که یک ویژگی چند بار خوانده شده است:
from unittest.mock import PropertyMock, patch

class User:
@property
def name(self):
return "Ali"


with patch.object(
User,
"name",
new_callable=PropertyMock
) as mock_name:

mock_name.return_value = "Test"

user = User()

print(user.name)
print(user.name)

mock_name.assert_called_with()
print(mock_name.call_count)

خروجی:
Test
Test
2

نکته مهم
PropertyMock باید روی کلاس یا شیءای قرار بگیرد که Property از آن تعریف شده است. در مثال بالا، آن را روی کلاس User قرار دادیم.
همچنین برای تغییر مقدار Property از mock_name.return_value و برای بررسی مقداردهی آن می‌توان از mock_name.assert_called_once_with(value) استفاده کرد.
🎯 تمرین
کلاسی به نام Account بسازید که یک Property به نام balance داشته باشد و مقدار اصلی آن 2000 باشد.
سپس با PropertyMock مقدار آن را در تست به 5000 تغییر دهید و بررسی کنید که مقدار اصلی پس از پایان Patch دوباره قابل‌دسترسی باشد.
پست ۲۶۵ از دوره جامع Python 🐍
👍1
🇮🇷 ۱۳ آبان | روز دانش‌آموز و روز مبارزه با استکبار جهانی

۱۳ آبان، یادآور روزهایی است که دانش‌آموزان و دانشجویان ایرانی برای استقلال، آزادی و آینده کشورشان ایستادگی کردند.

این روز فرصتی است برای یادآوری اهمیت آگاهی، علم، تفکر و تلاش نسل جوان در ساختن آینده‌ای بهتر.

ما باور داریم که قدرت واقعی یک ملت، در دانش، آگاهی و توانایی ساختن آن نهفته است.

بیایید با یادگیری، خلاقیت و پیشرفت علمی، سهمی در ساختن آینده داشته باشیم.

🌱 آینده را کسانی می‌سازند که امروز برای یادگرفتن تلاش می‌کنند.

🇮🇷 روز دانش‌آموز گرامی باد.
👍1👎1