مرکزی مواد پر جائیں

ٹیسٹنگ کے لیے ⁦Solidity⁩ سمارٹ کنٹریکٹس کو موک (mock) کیسے کریں

Solidity
سمارٹ کنٹریکٹس
ٹیسٹنگ
موکنگ
درمیانی
مارکس واس
۲ مئی، ۲۰۲۰
5 منٹ کا مطالعہ

موک آبجیکٹس (Mock objects) (opens in a new tab) آبجیکٹ اورینٹڈ پروگرامنگ میں ایک عام ڈیزائن پیٹرن ہیں۔ پرانے فرانسیسی لفظ 'mocquer' سے ماخوذ، جس کا مطلب 'مذاق اڑانا' ہے، یہ 'کسی حقیقی چیز کی نقل کرنے' میں تبدیل ہو گیا جو دراصل ہم پروگرامنگ میں کرتے ہیں۔ براہ کرم اپنے سمارٹ کنٹریکٹس کا مذاق صرف اسی صورت میں اڑائیں اگر آپ چاہیں، لیکن جب بھی ممکن ہو انہیں موک (mock) کریں۔ یہ آپ کی زندگی کو آسان بناتا ہے۔

موکس (mocks) کے ساتھ کنٹریکٹس کی یونٹ ٹیسٹنگ

کسی کنٹریکٹ کو موک کرنے کا بنیادی مطلب اس کنٹریکٹ کا ایک دوسرا ورژن بنانا ہے جو بالکل اصل کی طرح برتاؤ کرتا ہے، لیکن اس طریقے سے جسے ڈیولپر آسانی سے کنٹرول کر سکے۔ آپ کا اکثر ایسے پیچیدہ کنٹریکٹس سے واسطہ پڑتا ہے جہاں آپ صرف کنٹریکٹ کے چھوٹے حصوں کی یونٹ ٹیسٹنگ کرنا چاہتے ہیں۔ مسئلہ یہ ہے کہ کیا ہو اگر اس چھوٹے سے حصے کی ٹیسٹنگ کے لیے ایک بہت ہی مخصوص کنٹریکٹ کی حالت درکار ہو جس تک پہنچنا مشکل ہو؟

آپ ہر بار پیچیدہ ٹیسٹ سیٹ اپ لاجک لکھ سکتے ہیں جو کنٹریکٹ کو مطلوبہ حالت میں لائے یا آپ ایک موک لکھ سکتے ہیں۔ وراثت (inheritance) کے ساتھ کنٹریکٹ کو موک کرنا آسان ہے۔ بس ایک دوسرا موک کنٹریکٹ بنائیں جو اصل سے وراثت میں ملے۔ اب آپ اپنے موک میں فنکشنز کو اوور رائیڈ (override) کر سکتے ہیں۔ آئیے اسے ایک مثال سے دیکھتے ہیں۔

مثال: پرائیویٹ ERC-20

ہم ایک مثال کے طور پر ERC-20 کنٹریکٹ استعمال کرتے ہیں جس کا ایک ابتدائی پرائیویٹ وقت ہوتا ہے۔ مالک پرائیویٹ صارفین کا انتظام کر سکتا ہے اور شروع میں صرف انہیں ٹوکن وصول کرنے کی اجازت ہوگی۔ ایک بار جب ایک خاص وقت گزر جائے گا، تو ہر کسی کو ٹوکن استعمال کرنے کی اجازت ہوگی۔ اگر آپ جاننا چاہتے ہیں، تو ہم نئے اوپن زیپلن کنٹریکٹس v3 سے _beforeTokenTransfer (opens in a new tab) ہک (hook) استعمال کر رہے ہیں۔

اور اب آئیے اسے موک کرتے ہیں۔

آپ کو درج ذیل میں سے کوئی ایک ایرر میسج ملے گا:

  • PrivateERC20Mock.sol: TypeError: Overriding function is missing "override" specifier.
  • PrivateERC20.sol: TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?.

چونکہ ہم نیا 0.6 Solidity ورژن استعمال کر رہے ہیں، اس لیے ہمیں ان فنکشنز کے لیے virtual کی ورڈ شامل کرنا ہوگا جنہیں اوور رائیڈ کیا جا سکتا ہے اور اوور رائیڈنگ فنکشن کے لیے اوور رائیڈ کرنا ہوگا۔ تو آئیے انہیں دونوں isPublic فنکشنز میں شامل کرتے ہیں۔

اب اپنے یونٹ ٹیسٹس میں، آپ اس کے بجائے PrivateERC20Mock استعمال کر سکتے ہیں۔ جب آپ پرائیویٹ استعمال کے وقت کے دوران برتاؤ کو ٹیسٹ کرنا چاہتے ہیں، تو setIsPublic(false) استعمال کریں اور اسی طرح عوامی استعمال کے وقت کی ٹیسٹنگ کے لیے setIsPublic(true) استعمال کریں۔ یقیناً ہماری مثال میں، ہم اوقات کو اسی کے مطابق تبدیل کرنے کے لیے صرف ٹائم ہیلپرز (time helpers) (opens in a new tab) کا استعمال بھی کر سکتے تھے۔ لیکن موکنگ کا خیال اب واضح ہو جانا چاہیے اور آپ ایسے منظرناموں کا تصور کر سکتے ہیں جہاں صرف وقت کو آگے بڑھانا اتنا آسان نہیں ہوتا۔

بہت سے کنٹریکٹس کو موک کرنا

اگر آپ کو ہر ایک موک کے لیے ایک اور کنٹریکٹ بنانا پڑے تو یہ الجھن کا باعث بن سکتا ہے۔ اگر یہ آپ کو پریشان کرتا ہے، تو آپ MockContract (opens in a new tab) لائبریری پر ایک نظر ڈال سکتے ہیں۔ یہ آپ کو فوری طور پر کنٹریکٹس کے برتاؤ کو اوور رائیڈ اور تبدیل کرنے کی اجازت دیتی ہے۔ تاہم، یہ صرف کسی دوسرے کنٹریکٹ کی کالز کو موک کرنے کے لیے کام کرتی ہے، اس لیے یہ ہماری مثال کے لیے کام نہیں کرے گی۔

موکنگ اور بھی زیادہ طاقتور ہو سکتی ہے

موکنگ کی طاقتیں یہیں ختم نہیں ہوتیں۔

  • فنکشنز شامل کرنا: نہ صرف کسی مخصوص فنکشن کو اوور رائیڈ کرنا مفید ہے، بلکہ اضافی فنکشنز شامل کرنا بھی فائدہ مند ہے۔ ٹوکنز کے لیے ایک اچھی مثال صرف ایک اضافی mint فنکشن کا ہونا ہے تاکہ کسی بھی صارف کو مفت میں نئے ٹوکن حاصل کرنے کی اجازت مل سکے۔
  • ٹیسٹ نیٹس میں استعمال: جب آپ اپنی غیر مرکزی ایپلی کیشن (dapp) کے ساتھ ٹیسٹ نیٹس پر اپنے کنٹریکٹس کو تعینات کرتے اور ٹیسٹ کرتے ہیں، تو ایک موکڈ ورژن استعمال کرنے پر غور کریں۔ فنکشنز کو اوور رائیڈ کرنے سے گریز کریں جب تک کہ آپ کو واقعی ایسا نہ کرنا پڑے۔ آخر کار آپ اصل لاجک کو ٹیسٹ کرنا چاہتے ہیں۔ لیکن مثال کے طور پر ایک ری سیٹ (reset) فنکشن شامل کرنا مفید ہو سکتا ہے جو کنٹریکٹ کی حالت کو شروع سے ری سیٹ کر دیتا ہے، کسی نئی تعیناتی کی ضرورت نہیں ہوتی۔ ظاہر ہے کہ آپ اسے مین نیٹ کنٹریکٹ میں نہیں رکھنا چاہیں گے۔