Solidity
SC Truffle 測試:返回域對象?
在 Truffle 中進行一些測試以更加熟悉環境,但遇到了問題。
我想要做什麼
使用以下功能測試智能合約:
// Register an item using an identifier type (no., PID, barcode, etc.), the actual identifier/code, and a description function registerItem(string memory _identifier, string memory _code, string memory _description) public { // Make sure the item does not already exists/is not already registered require(!itemExists[keccak256(abi.encodePacked(_identifier,_code))]); // Create an Item struct in memory that stores the item data Item memory newItem; newItem.identifier = _identifier; newItem.code = _code; newItem.description = _description; // Map hash of item details to true/bring item into existence itemExists[keccak256(abi.encodePacked(_identifier,_code))] = true; // Increment tokenCounter; tokenCounter ++; // Set unique tokenId using tokenCounter uint256 tokenId = tokenCounter; // Map the tokenId to the item tokenIdtoItem[tokenId] = newItem; // Mint the token using ERC721 mint method, which checks if the token is already owned and if not sets it to the new owner ERC721Token.mint(tokenId); //Emit event emit ItemRegistered(tokenId, _identifier, _code); } // Get item details by providing a tokenId function getItemByToken(uint256 _tokenId) public view returns (string memory identifier, string memory code, string memory description) { Item memory returnItem = tokenIdtoItem[_tokenId]; return(returnItem.identifier,returnItem.code,returnItem.description); }
我正在測試它:
const assetTracker = artifacts.require("AssetTracker"); contract("AssetTracker contract test", async accounts => { it("should register an item", async () => { let instance = await assetTracker.deployed(); await instance.registerItem("Barcode", "13456-fgs", "This is the first dummy item.", { from: accounts[0]}); assert.equal(instance.getItemByToken(1), ["Barcode", "13456-fgs", "This is the first dummy item."]); // assert.equal(instance.ownerOf(1), accounts[0], "token is not owned by any or the correct user"); }); });
在 ganache 客戶端上的 Truffle 控制台中進行測試時得到的結果:
Contract: AssetTracker contract test 1) should register an item Events emitted during test: --------------------------- Transfer(_from: <indexed>, _to: <indexed>, _tokenId: <indexed>) ItemRegistered(_tokenId: <indexed>, _identifier: <indexed>, _code: <indexed>) --------------------------- 0 passing (237ms) 1 failing 1) Contract: AssetTracker contract test should register an item: AssertionError: expected { domain: { domain: null, _events: { removeListener: [Function: updateExceptionCapture], newListener: [Function: updateExceptionCapture], error: [Function: debugDomainError] }, _eventsCount: 3, _maxListeners: undefined, members: [], _errorHandler: [Function], enter: [Function], exit: [Function], add: [Function], remove: [Function], run: [Function], intercept: [Function], bind: [Function], setMaxListeners: [Function: setMaxListeners], getMaxListeners: [Function: getMaxListeners], emit: [Function], addListener: [Function: addListener], on: [Function: addListener], prependListener: [Function: prependListener], once: [Function: once], prependOnceListener: [Function: prependOnceListener], removeListener: [Function: removeListener], off: [Function: removeListener], removeAllListeners: [Function: removeAllListeners], listeners: [Function: listeners], rawListeners: [Function: rawListeners], listenerCount: [Function: listenerCount], eventNames: [Function: eventNames] } } to equal [ Array(3) ] at Context.it (test\assettracker.js:7:12) at process._tickCallback (internal/process/next_tick.js:68:7) 1
關於正在發生的事情有什麼想法嗎?當我在控制台中執行命令失去(例如遷移、連接到契約、執行功能)時,一切正常。
提前致謝。小心!
您應該使用 await 呼叫合約方法,如下所示。
const assetTracker = artifacts.require("AssetTracker"); contract("AssetTracker contract test", async accounts => { it("should register an item", async () => { let instance = await assetTracker.deployed(); await instance.registerItem("Barcode", "13456-fgs", "This is the first dummy item.", { from: accounts[0]}); assert.equal(await instance.getItemByToken(1), ["Barcode", "13456-fgs", "This is the first dummy item."]); // assert.equal(instance.ownerOf(1), accounts[0], "token is not owned by any or the correct user"); }); });
您還應該考慮使用 beforeEach 方法來重建實例,而不保留跨各種測試方法的狀態。
let instance; beforeEach('setup contract instance for each test case execution', async () => { instance = await assetTracker.new(); });
並使用如下所示,
it("should register an item", async () => { await instance.registerItem("Barcode", "13456-fgs", "This is the first dummy item.", { from: accounts[0]}); assert.equal(await instance.getItemByToken(1), ["Barcode", "13456-fgs", "This is the first dummy item."]); // assert.equal(instance.ownerOf(1), accounts[0], "token is not owned by any or the correct user"); });
希望這可以幫助。