Truffle

如何在 truffle 測試 javascript 中擷取“還原”錯誤?

  • December 15, 2021

如何在用 javascript 編寫的松露測試中擷取“還原”錯誤?

Error: VM Exception while processing transaction: revert

這是測試契約的一部分,

 function doRevert() public {
   revert();
 }

這是我測試javascript的一部分,

 it("test1.....", async() => {
   let instant = await myContract.deployed();    

   await instant.doRevert();
.
.
.

我不想在第一個測試步驟中停止我的測試程式碼。我搜尋了我可以導入expectThrow.js,但我無法導入它,與此處相同的問題。我知道這個問題與How can you handle an expected throw in a contract test using truffle and ethereum-testRPC 非常相關?,但仍然無法弄清楚如何使用庫,expectThrow.js並且不推薦使用 throw ,所以還有其他方法可以做到這一點嗎?

舉例回答:

假設您有一個只能由合約的所有者(部署者)呼叫的函式。

如果它被所有者以外的任何人呼叫,那麼它會恢復(require帶有false條件)。

文件exceptions.js

module.exports.errTypes = {
   revert            : "revert",
   outOfGas          : "out of gas",
   invalidJump       : "invalid JUMP",
   invalidOpcode     : "invalid opcode",
   stackOverflow     : "stack overflow",
   stackUnderflow    : "stack underflow",
   staticStateChange : "static state change"
}

module.exports.tryCatch = async function(promise, errType) {
   try {
       await promise;
       throw null;
   }
   catch (error) {
       assert(error, "Expected an error but did not get one");
       assert(error.message.startsWith(PREFIX + errType), "Expected an error starting with '" + PREFIX + errType + "' but got '" + error.message + "' instead");
   }
};

const PREFIX = "VM Exception while processing transaction: ";

文件MyContractTest.js

contract("MyContractTest", function(accounts) {
   let myContract;
   let owner    = accounts[0];
   let nonOwner = accounts[1];
   let tryCatch = require("./exceptions.js").tryCatch;
   let errTypes = require("./exceptions.js").errTypes;

   describe("sanity assertion:", function() {
       before(async function() {
           myContract = await artifacts.require("MyContract.sol").new();
       });
       it("should complete successfully", async function() {
           await myContract.func({from: owner});
       });
       it("should abort with an error", async function() {
           await tryCatch(myContract.func({from: nonOwner}), errTypes.revert);
       });
   });
});

更新:版本 2

我想用稍微簡單的程式碼來更新這個答案。它的行為應該是相同的,但它在測試本身中“節省了一些字元”,從而提高了可讀性並允許更容易維護。

文件exceptions.js

const PREFIX = "Returned error: VM Exception while processing transaction: ";

async function tryCatch(promise, message) {
   try {
       await promise;
       throw null;
   }
   catch (error) {
       assert(error, "Expected an error but did not get one");
       assert(error.message.startsWith(PREFIX + message), "Expected an error starting with '" + PREFIX + message + "' but got '" + error.message + "' instead");
   }
};

module.exports = {
   catchRevert            : async function(promise) {await tryCatch(promise, "revert"             );},
   catchOutOfGas          : async function(promise) {await tryCatch(promise, "out of gas"         );},
   catchInvalidJump       : async function(promise) {await tryCatch(promise, "invalid JUMP"       );},
   catchInvalidOpcode     : async function(promise) {await tryCatch(promise, "invalid opcode"     );},
   catchStackOverflow     : async function(promise) {await tryCatch(promise, "stack overflow"     );},
   catchStackUnderflow    : async function(promise) {await tryCatch(promise, "stack underflow"    );},
   catchStaticStateChange : async function(promise) {await tryCatch(promise, "static state change");},
};

文件MyContractTest.js

contract("MyContractTest", function(accounts) {
   let myContract;
   let owner       = accounts[0];
   let nonOwner    = accounts[1];
   let catchRevert = require("./exceptions.js").catchRevert;

   describe("sanity assertion:", function() {
       before(async function() {
           myContract = await artifacts.require("MyContract.sol").new();
       });
       it("should complete successfully", async function() {
           await myContract.func({from: owner});
       });
       it("should abort with an error", async function() {
           await catchRevert(myContract.func({from: nonOwner}));
       });
   });
});

引用自:https://ethereum.stackexchange.com/questions/48627