Есть ли (идиоматический) способ тестирования результата функции ввода-вывода в Clojure?

У меня есть функция, которая сохраняет текст в файл:

(defn save-keypair
  "saves keypair to ~/.ssb-clj/secret"
  [pair file-path]
  (let [public-key-string (->> (:public pair) (.array) (byte-array) (b64/encode) (bs/to-string))
        secret-key-string (->> (:secret pair) (.array) (byte-array) (b64/encode) (bs/to-string))]
    (spit file-path (str "Public Key: " public-key-string))
    (spit file-path (str "\nPrivate Key: " secret-key-string) :append true)))

Он работает нормально (в настоящее время проверяет, просто открывая файл и просматривая его сам). Однако я хотел бы написать реальный тест, чтобы убедиться, что все работает правильно. Есть ли идиоматический способ сделать это в Clojure?

2 ответа

Изучите использование with-redefs, как часть ваших модульных тестов. В вашем случае вы, вероятно, захотите объединить запись открытого и закрытого ключей в единую форму, которую мы можем использовать для теста:

;; compute public-key-string and private-key-string as before
(let [contents (format "Public Key: %s\nPrivate Key: %s"
                        public-key-string secret-key-string)]
 (spit file-path contents)

Тест может быть примерно таким:

(deftest saving-keypair
  (testing "Successful save"
    (let [file-mock (atom nil)]

      ;; During this test we redefine `spit` to save into the atom defined above
      (with-redefs [spit (fn [path data] (reset! file-mock {:path path :data data}))]

        ;; Perform IO action
        (save-keypair "~/.ssb-clj/secret" {:public "XXXX" :private "YYYYY"})

        ;; Test if the expected data was saved in the file-mock
        (is (= {:path "~/.ssb-clj/secret" :data "Public key: XXXYYYZZZ\nXXXYYYZZ"}
               @file-mock))

Используйте взаимодействие Java с File

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/File.html

В частности, см. File.createTempFile() и либо file.delete() или file.deleteOnExit(). Итак, вы создаете временный файл, используете его в своем модульном тесте, читаете только что написанный файл и проверяете его содержимое. Затем либо удалите файл явно (в идеале внутри try / finally) с автоматическим удалением в качестве резервной копии.

В зависимости от того, как вы настроили ожидаемые результаты в своих тестах, вам может быть полезно следующее:

Эти вспомогательные функции особенно полезны для вывода текстового файла, где наличие завершающего newlinechar может зависеть от ОС. Они также помогают игнорировать различия из-за того, что "новая строка" является CR, CR/LF или LF.

Другие вопросы по тегам