You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Truffle测试Solidity合约时报_character.getName非函数错误

问题描述

执行truffle test命令运行智能合约测试用例时,触发如下报错:

TypeError: _character.getName is not a function

测试预期逻辑:部署Game合约后调用createCharacter方法创建角色,通过getCharacter获取角色合约地址,实例化Character合约后调用getName方法校验角色名是否和传入参数一致。

环境信息
  • Truffle v5.5.20 (core: 5.5.20)
  • Ganache v7.2.0
  • Solidity - 0.8.15 (solc-js)
  • Node v16.15.1
  • Web3.js v1.7.4
相关代码

测试文件代码

let Game = artifacts.require("./Game.sol");
let Character = artifacts.require("./Character.sol");

const PROVIDED_NAME = "TEST";

contract("Game", (accounts) => {

    let creatorAccount = accounts[0];

    it("should create a character with the name provided", () => {
        let _game;
        let _character;

        return Game.deployed()
            .then(instance => {
                _game = instance;
                return _game.createCharacter(PROVIDED_NAME, { from: creatorAccount });
            })
            .then(result => {
                return _game.getCharacter();
            })
            .then(character => {
                _character = Character.at(character);
                return _character.getName();
            })
            .then(name => {
                assert.equal(name, PROVIDED_NAME, "Failed to create a character with the provided name");
            });
    });
});

Character.sol合约代码

// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

contract Character {
    string private _name;

    constructor(string memory name) public {
        _name = name;
    }

    function getName() public view returns (string memory) {
        return _name;
    }
}
排查解决步骤
  • 第一步:校验getCharacter()返回值格式
    这是该报错最常见的诱因。Truffle v5调用合约view/pure方法时,即使方法只返回单个值,也会返回一个带索引的类数组结果对象,而非直接返回值本身。你可以在获取character的回调中加console.log(character)打印返回内容,如果输出类似Result { '0': '0x.....' }的结构,说明你直接把整个结果对象传入了Character.at(),而非实际的地址字符串,自然无法得到正确的合约实例、找不到getName方法。
    修正对应代码段,取结果的第一个索引位作为地址即可:
    .then(character => {
        // 取返回结果的第一个值,即实际的角色合约地址
        const characterAddr = character[0];
        _character = Character.at(characterAddr);
        return _character.getName();
    })
    
  • 第二步:校验Game合约的逻辑正确性
    确认Game合约中两个方法的实现符合预期:
    1. createCharacter方法中确实通过new Character(name)的方式创建了Character合约实例,且将实例地址正确存入了合约状态变量
    2. getCharacter方法的返回值类型为address,返回值为前述存储的Character合约地址,没有返回零地址或其他不相关的状态变量
  • 第三步:修正Character合约的构造函数兼容问题
    Solidity 0.7.0及以上版本中,构造函数无需显式声明public可见性,保留该写法虽然不会直接触发当前报错,但可能在后续编译、部署环节触发异常,建议修改为:
    constructor(string memory name) {
        _name = name;
    }
    
  • 第四步:验证合约实例有效性
    实例化_character后,可以打印_character对象确认其是否挂载了getName方法,如果方法不存在,优先回到第一步检查传入的地址是否为合法的20字节EVM地址字符串。

内容的提问来源于stack exchange,提问作者Taki Eddine Abdesselam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:51:22