我希望使用with-redefs
来模拟STDIN的用户输入。
首先,我正在测试不正确的输入,应该重新询问用户输入。然后,应该给出正确的输入。
有没有办法使用with-redefs
将不同的值绑定到给定的符号?
我试图获得此功能:
(with-redefs [read-line (fn [] "HI")
read-line (fn [] "OK")]
(do (println (read-line)) ;; -> "HI"
(println (read-line)))) ;; -> "OK"
答案 0 :(得分:7)
不是特别的,但是你总是可以用某种状态'让兰比达'过来!
(let [a (atom ["a" "b"])]
(defn f []
(let [r (first @a)]
(swap! a rest)
r)))
(f) ;; "a"
(f) ;; "b"
(f) ;; nil
在你的特定情况下,有一个生成'有状态'函数的函数是有意义的,所以一个完整的例子是:
(defn maker [l]
(let [a (atom l)]
(fn []
(let [r (first @a)]
(swap! a rest)
r))))
(with-redefs [read-line (maker ["HI" "OK"])]
(do (println (read-line)) ;; -> "HI"
(println (read-line)))) ;; -> "OK"
答案 1 :(得分:4)
为此目的,您可能会更乐意使用with-in-str
:
(with-in-str "Hello"
(println (read-line)))
(with-in-str "There"
(println (read-line))))
结果:
(read-line) => "Hello"
(read-line) => "There"
请务必始终向The Clojure Cheatsheet打开浏览器标签,并经常仔细阅读!
答案 2 :(得分:0)
以下是我认为可能有用的代码示例:
(ns project.test
(:require [clojure.test :refer :all]))
(deftest test-user-input
(testing "wrong input"
(with-in-str "some wrong input"
(is (thrown?
SomeExceptionClass
(call-your-function)))))
(testing "correct input"
(with-in-str "some correct input"
(let [result (call-your-function)]
(is (= result [:proper :data]))))))