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

Clojure测试中如何为接收文件的代码模拟stdin字符串输入

方案1:核心逻辑抽离(最推荐)

你当前的写法把输入源解析和业务逻辑耦合在了-main入口里,最优解是把纯业务逻辑抽成独立函数,完全和输入来源解绑:

;; 抽离核心处理逻辑:接收行序列作为输入,直接处理输出
(defn process-lines [lines]
  (print-all (input-received lines)))

;; -main 只负责处理入口参数,适配不同输入源
(defn -main
  [& args]
  (process-lines (-> (or (first args) *in*)
                     clojure.java.io/reader
                     line-seq)))

测试的时候直接调用纯逻辑函数,不需要绕文件或者stdin绑定,写法最简洁:

(testing "Create account"
  (let [input "{\"account\": {\"active-card\": true, \"available-limit\": 100}}"
        expected (str (cheshire/generate-string {:account {:active-card true :available-limit 100} :violations []}) \newline)]
    (is (= expected (with-out-str (process-lines [input]))))))

方案2:兼容字符串输入的最小修改

如果不想调整现有代码结构,只需要修改read-input!函数,让它能区分输入是文件路径还是JSON内容即可:

(defn read-input! [input]
  (line-seq
   (clojure.java.io/reader
    ;; 判断输入是JSON内容还是文件路径,你也可以按自己的业务规则调整判断条件
    (if (.startsWith (str input) "{")
      (java.io.StringReader. input)
      input))))

修改后你期望的测试写法可以直接运行,不需要额外调整:

(testing "Create account"
    (is (= (str (cheshire/generate-string {:account {:active-card true :available-limit 100} :violations []}) \newline)
           (with-out-str
             (io/-main "{\"account\": {\"active-card\": true, \"available-limit\": 100}}")))))

关于你自己摸索的方案

你用with-in-str绑定stdin的方案是可以正常运行的,缺点是需要操作全局输入流绑定,多测试用例并行执行时可能有冲突风险,同时嵌套层数更多,不如抽离纯逻辑的方案简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:51:03