手把手教你开发dapp (3)_tiknovel-最新最全的nft,web3,AI技术资讯技术社区

手把手教你开发dapp (3)

2022-03-25 10:27:01  浏览:424  作者:管理员
使用 Solidity 测试智能合约¶展开本节Truffle 在智能合约测试方面非常灵活,因为测试可以用 JavaScript 或 Solidity 编写。在本教...

使用 Solidity 测试智能合约


展开本节Truffle 在智能合约测试方面非常灵活,因为测试可以用 JavaScript 或 Solidity 编写。在本教程中,我们将使用 Solidity 编写测试。


  1. TestAdoption.sol在目录中创建一个名为的新文件test/

  2. 将以下内容添加到TestAdoption.sol文件中:

pragma solidity ^0.5.0;import "truffle/Assert.sol";import "truffle/DeployedAddresses.sol";import "../contracts/Adoption.sol";contract TestAdoption { // The address of the adoption contract to be tested Adoption adoption = Adoption(DeployedAddresses.Adoption()); // The id of the pet that will be used for testing uint expectedPetId = 8; // The expected owner of adopted pet is this contract address expectedAdopter = address(this);}

我们以 3 个进口开始合同:

  • Assert.sol: 为我们提供了在测试中使用的各种断言。在测试中,断言检查诸如相等、不等或空虚之类的东西,以从我们的测试中返回通过/失败。这是 Truffle 中包含的断言的完整列表

  • DeployedAddresses.sol:在运行测试时,Truffle 会将正在测试的合约的新实例部署到区块链。该智能合约获取已部署合约的地址。

  • Adoption:我们要测试的智能合约。

注意:前两个导入是指全局 Truffle 文件,而不是 `truffle` 目录。你不应该在 `test/` 目录中看到 `truffle` 目录。

然后我们定义了三个合约范围的变量: * 首先,一个包含要测试的智能合约,调用DeployedAddresses智能合约来获取它的地址。* 其次,宠物的id,将用于测试收养功能。* 第三,由于 TestAdoption 合约将发送交易,我们将预期的采用者地址设置为this,这是一个合约范围的变量,用于获取当前合约的地址。

测试采用()函数

要测试该adopt()函数,请回想一下,成功后它会返回给定的petIdadopt()我们可以通过将返回值与我们传入的 ID进行比较来确保返回的 ID 是正确的。

  1. TestAdoption.sol在智能合约中,在声明之后添加以下函数expectedPetId

// Testing the adopt() functionfunction testUserCanAdoptPet() public { uint returnedId = adoption.adopt(expectedPetId); Assert.equal(returnedId, expectedPetId, "Adoption of the expected pet should match what is returned.");}

注意事项:

  • 我们将之前声明的智能合约称为expectedPetId.

  • 最后,我们将实际值、预期值和失败消息(如果测试未通过,则会打印到控制台)传递给Assert.equal().

测试单个宠物主人的检索

从上面记住,公共变量具有自动 getter 方法,我们可以检索上面采用测试存储的地址。存储的数据将在我们的测试期间持续存在,因此我们对expectedPetId上述宠物的采用可以通过其他测试来检索。

  1. 在之前添加的函数下方添加此函数TestAdoption.sol

// Testing retrieval of a single pet's ownerfunction testGetAdopterAddressByPetId() public { address adopter = adoption.adopters(expectedPetId); Assert.equal(adopter, expectedAdopter, "Owner of the expected pet should be this contract");}

在获得采用合约存储的采用者地址后,我们像上面那样断言平等。

测试所有宠物主人的检索

由于数组只能在给定单个键的情况下返回单个值,因此我们为整个数组创建自己的 getter。

  1. 在之前添加的函数下方添加此函数TestAdoption.sol

// Testing retrieval of all pet ownersfunction testGetAdopterAddressByPetIdInArray() public { // Store adopters in memory rather than contract's storage address[16] memory adopters = adoption.getAdopters(); Assert.equal(adopters[expectedPetId], expectedAdopter, "Owner of the expected pet should be this contract");}

注意内存属性adoptersmemory 属性告诉 Solidity 将值临时存储在内存中,而不是将其保存到合约的存储中。由于adopters是一个数组,并且我们从第一次采用测试中知道我们采用了 pet expectedPetId,我们将测试合约地址与expectedPetId数组中的位置进行比较。

使用 JavaScript 测试智能合约


展开本节Truffle 在智能合约测试方面非常灵活,因为测试可以用 JavaScript 或 Solidity 编写。在本教程中,我们将使用 Chai 和 Mocha 库在 Javascript 中编写测试。


  1. testAdoption.test.js在目录中创建一个名为的新文件test/

  2. 将以下内容添加到testAdoption.test.js文件中:


const Adoption = artifacts.require("Adoption");contract("Adoption", (accounts) => {
  let adoption;
  let expectedAdopter;
  before(async () => {
      adoption = await Adoption.deployed();
  });
  describe("adopting a pet and retrieving account addresses", async () => {
    before("adopt a pet using accounts[0]", async () => {
      await adoption.adopt(8, { from: accounts[0] });
      expectedAdopter = accounts[0];
    });
  });});
我们通过导入来启动合约: * Adoption:我们想要测试的智能合约。我们通过使用导入我们的 Adoption合约 开始我们的测试artifacts.require


注意:在编写这个测试时,我们的回调函数接受参数accounts这为我们提供了使用此测试时网络上可用的帐户。

然后,我们利用before为以下内容提供初始设置: * 采用 id 为 8 的宠物并将其分配给网络上测试帐户中的第一个帐户。* 此功能稍后用于检查是否petId: 8已被accounts[0].

### 测试采用函数

要测试该adopt函数,请回想一下,成功后它会返回给定的adopter我们可以确保返回基于给定 petID 的采用者,并与函数expectedAdopter内部进行比较adopt

  1. 在代码块testAdoption.test.js声明之后,在测试文件中添加以下函数。before

describe("adopting a pet and retrieving account addresses", async () => {
  before("adopt a pet using accounts[0]", async () => {
    await adoption.adopt(8, { from: accounts[0] });
    expectedAdopter = accounts[0];
  });
  it("can fetch the address of an owner by pet id", async () => {
    const adopter = await adoption.adopters(8);
    assert.equal(adopter, expectedAdopter, "The owner of the adopted pet should be the first account.");
  });});

注意事项:

  • 我们调用智能合约的方法adopters来看看哪个地址收养了带有petID8 的宠物。

  • TruffleChai为用户导入,因此我们可以使用这些assert函数。我们将实际值、期望值和失败消息(如果测试未通过,则会打印到控制台)传递给assert.equal().

### 测试所有宠物主人的检索

由于数组只能在给定单个键的情况下返回单个值,因此我们为整个数组创建自己的 getter。

  1. 在之前添加的函数下方添加此函数testAdoption.test.js


it("can fetch the collection of all pet owners' addresses", async () => {
  const adopters = await adoption.getAdopters();
  assert.equal(adopters[8], expectedAdopter, "The owner of the adopted pet should be in the collection.");});
由于采用者是一个数组,并且我们从第一次采用测试中知道我们采用了 petId8 的宠物,因此我们将合约的地址与我们期望找到的地址进行比较。


运行测试

  1. 回到终端,运行测试:

truffle test
  1. 如果所有测试都通过,您将看到类似于以下内容的控制台输出:

Using network 'development'.Compiling your contracts...===========================> Compiling ./test/TestAdoption.sol> Artifacts written to /var/folders/z3/v0sd04ys11q2sh8tq38mz30c0000gn/T/test-11934-19747-g49sra.0ncrr> Compiled successfully using:
   - solc: 0.5.0+commit.1d4f565a.Emscripten.clang
  TestAdoption
    ✓ testUserCanAdoptPet (91ms)
    ✓ testGetAdopterAddressByPetId (70ms)
    ✓ testGetAdopterAddressByPetIdInArray (89ms)
  3 passing (670ms)

    评论区

    共 0 条评论
    • 这篇文章还没有收到评论,赶紧来抢沙发吧~

    【随机内容】

    返回顶部