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

为GitHub自动评分器实现Tasty-HUnit IO测试遇hDuplicateTo导出错误

解决IO函数测试的hDuplicateTo未导出问题及完整测试代码

问题分析

  1. hDuplicateTo未导出:该函数属于GHC内部模块GHC.IO.Handle,而非System.IO的默认导出列表,因此需要显式导入。
  2. 原测试逻辑错误:
    • 试图向只读的stdin写入内容会触发IO错误
    • 仅提供一行输入,但countLetters需要三次输入,与预期结果不匹配
    • 使用/dev/null无法提供测试所需的输入内容

完整测试代码

首先确保你的项目依赖包含tasty、tasty-hunit、directory和temporary,在cabal文件中添加:

build-depends:
  base >= 4.14 && < 5,
  tasty >= 1.4,
  tasty-hunit >= 0.10,
  directory >= 1.3,
  temporary >= 1.3

测试代码文件:

import Test.Tasty
import Test.Tasty.HUnit
import System.IO
import GHC.IO.Handle (hDuplicateTo, hDuplicate)
import System.Directory (removeFile)
import System.IO.Temp (writeSystemTempFile)

-- 目标函数(可根据实际情况调整导入)
countLetters :: IO [Int]
countLetters = do 
               putStr "First entry: "
               x <- getLine
               putStr "Second entry: "
               y <- getLine
               putStr "Third entry: "
               z <- getLine
               return [length x, length y, length z]

test_countLetters :: TestTree
test_countLetters = testCase "test_countLetters" $ do
  -- 保存原始stdin句柄,测试后恢复避免影响其他测试
  originalStdin <- hDuplicate stdin
  -- 创建临时文件并写入三次测试输入
  tempFile <- writeSystemTempFile "count_letters_input" "Haskell\nIs\nFun\n"
  -- 打开临时文件的读句柄
  inputHandle <- openFile tempFile ReadMode
  -- 将stdin重定向到临时文件读句柄
  hDuplicateTo inputHandle stdin
  -- 执行目标函数
  result <- countLetters
  -- 恢复原始stdin
  hDuplicateTo originalStdin stdin
  -- 清理资源
  hClose inputHandle
  removeFile tempFile
  -- 断言结果是否符合预期
  assertEqual "Count letters" [7,2,3] result

main :: IO ()
main = defaultMain $ testGroup "IO Function Tests"
  [ test_countLetters
  ]

代码说明

  • 使用临时文件提供测试输入,确保跨平台兼容性
  • 保存并恢复原始stdin,避免测试影响后续代码执行
  • 显式导入GHC.IO.Handle中的hDuplicateTo解决导出问题
  • 提供与预期结果匹配的三次输入(Haskell、Is、Fun),确保逻辑正确性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:04:59