முக்கிய உள்ளடக்கத்திற்குச் செல்லவும்

சோதனைக்காக Solidity ஸ்மார்ட் ஒப்பந்தங்களை மாக்கிங் (mocking) செய்வது எப்படி

Solidity
ஸ்மார்ட் ஒப்பந்தங்கள்
சோதனை
மாக்கிங்
இடைநிலையாளர்
மார்கஸ் வாஸ்
2 மே, 2020
3 நிமிட வாசிப்பு

மாக் ஆப்ஜெக்ட்கள் (Mock objects) (opens in a new tab) என்பது ஆப்ஜெக்ட்-ஓரியண்டட் (object-oriented) நிரலாக்கத்தில் ஒரு பொதுவான வடிவமைப்பு முறையாகும். 'கேலி செய்வது' என்ற பொருளைக் கொண்ட 'mocquer' என்ற பழைய பிரெஞ்சு வார்த்தையிலிருந்து வந்த இது, 'உண்மையான ஒன்றைப் பின்பற்றுவது' என்று உருவானது, இதுவே நாம் நிரலாக்கத்தில் செய்கிறோம். நீங்கள் விரும்பினால் மட்டுமே உங்கள் ஸ்மார்ட் ஒப்பந்தங்களை கேலி செய்யுங்கள், ஆனால் உங்களால் முடிந்த போதெல்லாம் அவற்றை மாக்கிங் (mock) செய்யுங்கள். இது உங்கள் வாழ்க்கையை எளிதாக்குகிறது.

மாக்குகளுடன் ஒப்பந்தங்களை யூனிட்-சோதனை செய்தல்

ஒரு ஒப்பந்தத்தை மாக்கிங் செய்வது என்பது அடிப்படையில் அந்த ஒப்பந்தத்தின் இரண்டாவது பதிப்பை உருவாக்குவதாகும், இது அசலைப் போலவே செயல்படுகிறது, ஆனால் டெவலப்பரால் எளிதாகக் கட்டுப்படுத்தக்கூடிய வகையில் இருக்கும். நீங்கள் பெரும்பாலும் சிக்கலான ஒப்பந்தங்களை உருவாக்குவீர்கள், அங்கு நீங்கள் ஒப்பந்தத்தின் சிறிய பகுதிகளை மட்டுமே யூனிட்-சோதனை செய்ய விரும்புவீர்கள். பிரச்சனை என்னவென்றால், இந்த சிறிய பகுதியைச் சோதிக்க மிகவும் குறிப்பிட்ட ஒப்பந்த நிலை தேவைப்பட்டால், அதை அடைவது கடினமாக இருக்குமே?

ஒப்பந்தத்தை தேவையான நிலைக்குக் கொண்டுவரும் சிக்கலான சோதனை அமைப்பு லாஜிக்கை நீங்கள் ஒவ்வொரு முறையும் எழுதலாம் அல்லது நீங்கள் ஒரு மாக்கை எழுதலாம். இன்ஹெரிட்டன்ஸ் (inheritance) மூலம் ஒரு ஒப்பந்தத்தை மாக்கிங் செய்வது எளிது. அசலில் இருந்து இன்ஹெரிட் செய்யும் இரண்டாவது மாக் ஒப்பந்தத்தை உருவாக்கவும். இப்போது நீங்கள் உங்கள் மாக்கிற்கு செயல்பாடுகளை ஓவர்ரைடு (override) செய்யலாம். இதை ஒரு உதாரணத்துடன் பார்ப்போம்.

எடுத்துக்காட்டு: பிரைவேட் ERC20

ஆரம்ப பிரைவேட் நேரத்தைக் கொண்ட ஒரு எடுத்துக்காட்டு ERC-20 ஒப்பந்தத்தைப் பயன்படுத்துகிறோம். உரிமையாளர் பிரைவேட் பயனர்களை நிர்வகிக்க முடியும் மற்றும் அவர்கள் மட்டுமே ஆரம்பத்தில் டோக்கன்களைப் பெற அனுமதிக்கப்படுவார்கள். ஒரு குறிப்பிட்ட நேரம் கடந்தவுடன், அனைவரும் டோக்கன்களைப் பயன்படுத்த அனுமதிக்கப்படுவார்கள். நீங்கள் ஆர்வமாக இருந்தால், புதிய OpenZeppelin ஒப்பந்தங்கள் v3 இலிருந்து _beforeTokenTransfer (opens in a new tab) ஹூக்கைப் பயன்படுத்துகிறோம்.

1pragma solidity ^0.6.0;
2
3import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
4import "@openzeppelin/contracts/access/Ownable.sol";
5
6contract PrivateERC20 is ERC20, Ownable {
7 mapping (address => bool) public isPrivateUser;
8 uint256 private publicAfterTime;
9
10 constructor(uint256 privateERC20timeInSec) ERC20("PrivateERC20", "PRIV") public {
11 publicAfterTime = now + privateERC20timeInSec;
12 }
13
14 function addUser(address user) external onlyOwner {
15 isPrivateUser[user] = true;
16 }
17
18 function isPublic() public view returns (bool) {
19 return now >= publicAfterTime;
20 }
21
22 function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
23 super._beforeTokenTransfer(from, to, amount);
24
25 require(_validRecipient(to), "PrivateERC20: invalid recipient");
26 }
27
28 function _validRecipient(address to) private view returns (bool) {
29 if (isPublic()) {
30 return true;
31 }
32
33 return isPrivateUser[to];
34 }
35}
அனைத்தையும் காட்டு

இப்போது அதை மாக்கிங் செய்வோம்.

1pragma solidity ^0.6.0;
2import "../PrivateERC20.sol";
3
4contract PrivateERC20Mock is PrivateERC20 {
5 bool isPublicConfig;
6
7 constructor() public PrivateERC20(0) {}
8
9 function setIsPublic(bool isPublic) external {
10 isPublicConfig = isPublic;
11 }
12
13 function isPublic() public view returns (bool) {
14 return isPublicConfig;
15 }
16}
அனைத்தையும் காட்டு

பின்வரும் பிழைச் செய்திகளில் ஒன்றைப் பெறுவீர்கள்:

  • 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 முக்கிய சொல்லைச் சேர்க்க வேண்டும் மற்றும் ஓவர்ரைடிங் செயல்பாட்டிற்கு override ஐச் சேர்க்க வேண்டும். எனவே அவற்றை இரண்டு isPublic செயல்பாடுகளிலும் சேர்ப்போம்.

இப்போது உங்கள் யூனிட் சோதனைகளில், அதற்குப் பதிலாக PrivateERC20Mock ஐப் பயன்படுத்தலாம். பிரைவேட் பயன்பாட்டு நேரத்தின் போது நடத்தையைச் சோதிக்க விரும்பினால், setIsPublic(false) ஐப் பயன்படுத்தவும், அதேபோல பொதுப் பயன்பாட்டு நேரத்தைச் சோதிக்க setIsPublic(true) ஐப் பயன்படுத்தவும். நிச்சயமாக எங்கள் எடுத்துக்காட்டில், நேரங்களை அதற்கேற்ப மாற்ற நேர உதவியாளர்களை (time helpers) (opens in a new tab) பயன்படுத்தலாம். ஆனால் மாக்கிங் பற்றிய யோசனை இப்போது தெளிவாக இருக்க வேண்டும், மேலும் நேரத்தை வெறுமனே முன்னேற்றுவது போல் எளிதாக இல்லாத காட்சிகளை நீங்கள் கற்பனை செய்து பார்க்கலாம்.

பல ஒப்பந்தங்களை மாக்கிங் செய்தல்

ஒவ்வொரு மாக்கிற்கும் நீங்கள் மற்றொரு ஒப்பந்தத்தை உருவாக்க வேண்டியிருந்தால் அது குழப்பமாக மாறும். இது உங்களுக்குத் தொந்தரவாக இருந்தால், நீங்கள் MockContract (opens in a new tab) லைப்ரரியைப் பார்க்கலாம். இது ஒப்பந்தங்களின் நடத்தைகளை உடனுக்குடன் ஓவர்ரைடு செய்யவும் மாற்றவும் உங்களை அனுமதிக்கிறது. இருப்பினும், இது மற்றொரு ஒப்பந்தத்திற்கான அழைப்புகளை மாக்கிங் செய்வதற்கு மட்டுமே செயல்படும், எனவே இது எங்கள் எடுத்துக்காட்டிற்கு வேலை செய்யாது.

மாக்கிங் இன்னும் சக்திவாய்ந்ததாக இருக்கும்

மாக்கிங்கின் சக்திகள் அத்துடன் முடிவதில்லை.

  • செயல்பாடுகளைச் சேர்த்தல்: ஒரு குறிப்பிட்ட செயல்பாட்டை ஓவர்ரைடு செய்வது மட்டுமல்லாமல், கூடுதல் செயல்பாடுகளைச் சேர்ப்பதும் பயனுள்ளதாக இருக்கும். டோக்கன்களுக்கான ஒரு நல்ல உதாரணம், எந்தவொரு பயனரும் புதிய டோக்கன்களை இலவசமாகப் பெற அனுமதிக்க கூடுதல் mint செயல்பாட்டைக் கொண்டிருப்பதாகும்.
  • டெஸ்ட்நெட்களில் (testnets) பயன்பாடு: உங்கள் dapp உடன் டெஸ்ட்நெட்களில் உங்கள் ஒப்பந்தங்களை டிப்ளாய் செய்து சோதிக்கும் போது, மாக்கிங் செய்யப்பட்ட பதிப்பைப் பயன்படுத்துவதைக் கவனியுங்கள். நீங்கள் உண்மையிலேயே செய்ய வேண்டியிருந்தால் தவிர, செயல்பாடுகளை ஓவர்ரைடு செய்வதைத் தவிர்க்கவும். எல்லாவற்றிற்கும் மேலாக உண்மையான லாஜிக்கை நீங்கள் சோதிக்க விரும்புகிறீர்கள். ஆனால் எடுத்துக்காட்டாக ஒரு ரீசெட் (reset) செயல்பாட்டைச் சேர்ப்பது பயனுள்ளதாக இருக்கும், இது ஒப்பந்த நிலையை ஆரம்பத்திற்கு மீட்டமைக்கிறது, புதிய டிப்ளாய்மென்ட் தேவையில்லை. வெளிப்படையாக நீங்கள் அதை ஒரு மெயின்நெட் (Mainnet) ஒப்பந்தத்தில் வைத்திருக்க விரும்ப மாட்டீர்கள்.

பக்கம் கடைசியாகப் புதுப்பிக்கப்பட்டது: 3 மார்ச், 2026

இந்த வழிகாட்டி பயனுள்ளதாக இருந்ததா?