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

如何对调用硬编码内部函数的Plutus合约HTTP接口编写测试用例

解决方案

方案1:条件编译注入测试控制逻辑(生产零侵入)

这是最适配你场景的方案,完全不需要修改f1的原有逻辑和入参,生产环境构建时不会残留任何测试相关代码:

  1. 给代码添加CPP预编译支持,拆分f2的实现为生产分支和测试分支:
{-# LANGUAGE CPP #-}

data ActualData = ActualData String String Integer
newtype Input = Input [ActualData]

#ifdef TEST_BUILD
import Data.IORef
import System.IO.Unsafe

-- 仅测试环境存在的全局变量,存储自定义测试输入
{-# NOINLINE testInputRef #-}
testInputRef :: IORef Input
testInputRef = unsafePerformIO $ newIORef defaultInput

-- 仅测试环境暴露的HTTP配置接口
setTestInput :: Contract () Schema Text ()
setTestInput = do
    customInput <- endpoint @"set-test-input"
    liftIO $ writeIORef testInputRef customInput

f2 :: Input
f2 = unsafePerformIO $ readIORef testInputRef
#else
-- 生产环境完全保留原有逻辑
f2 :: Input
f2 = defaultInput
#endif

-- 原有默认输入抽为公共常量
defaultInput :: Input
defaultInput = Input
    [ ActualData "BlackRock" "pkh1" 10
    , ActualData "GreenRock" "pkh2" 20
    ]

f1:: Contract () Schema Text () 
f1 = do
    let input = f2 
    -- 原有逻辑保持不变
    ...
  1. 测试流程:
  • 测试环境构建时添加-DTEST_BUILD编译参数,此时服务会额外暴露setTestInput的HTTP端点
  • 执行每个测试用例前,先调用setTestInput接口传入你需要的自定义输入
  • 再调用f1的HTTP接口,此时f1读取到的f2返回值就是你指定的测试输入
  • 生产环境构建时不添加TEST_BUILD宏,所有测试相关代码会被完全剔除,不需要做额外的JSON序列化适配,和原有生产代码完全一致

方案2:测试时重载f2实现(无需修改业务代码)

如果不想引入条件编译,可以在测试项目中重载f2的实现:

  • 测试模块导入业务模块时隐藏原有f2:import 业务模块名 hiding (f2)
  • 在测试模块内自定义f2的实现,返回对应测试用例需要的输入值
  • 测试构建的服务会使用重载后的f2实现,业务代码完全不需要改动

内容的提问来源于stack exchange,提问作者thirsty

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 07:27:02