我有以下代码从我的资源文件夹加载edn数据:
(defn load-data
[]
(->> (io/resource "news.edn")
slurp
edn/read-string))
我想通过模拟文件读取部分来对此进行测试,到目前为止,我已经拥有了:
(deftest loading-data
(is (= (edn/read-string (prn-str {:articles [{:title "ASAP Rocky released" :url "http://foo.com"}]})) (load-data))))
但是我知道这个测试很不稳定,因为如果edn文件名更改,内容或更新,则测试将失败。有什么想法吗?
答案 0 :(得分:4)
您想对此功能有什么信心?您是否担心news.edn不存在?您是否担心在某项资源上大吃大喝和/或edn阅读不起作用?
我的建议是分别测试您单独的问题
如果您担心news.edn不存在断言它的存在
如果您担心该功能的其余部分无法从edn转换,请添加新的签名以接受资源,然后在测试时提供另一个资源以对此进行断言
如果您担心文件的形状,则可以在将数据放入news.edn之前进行针对数据的测试。
然后,几年后再回到这些测试时,您会看到失败的明确原因,而不是因为在调试之前未知的N个可能原因而导致测试失败的原因
答案 1 :(得分:3)
您可以使用with-redefs
模拟出对函数的调用,即“在执行主体时临时重新定义Vars”。例如,
(deftest load-data-test
(with-redefs [slurp (constantly "{:a \"b\"}")]
(is (= (load-data) {:a "b"}))))
这样,slurp
范围内load-data
中的with-redefs
返回"{:a \"b\"}"
。
答案 2 :(得分:1)
正如其他人所建议的那样:模拟更少的事情。
这可能是您从构建Java测试中学到的。
如果您正确构造了函数,则可以单独进行测试,而无需产生副作用(例如读取文件)。
如果在示例中模拟slurp
,则说明您没有测试任何有意义的东西:实际上,您将测试标准函数edn/read-string
是否按预期工作。
答案 3 :(得分:1)
重写您的load-data
以接受要加载的文件名作为参数(然后在您的“ main”中使用news.edn
进行调用)。这使其功能更强大,并且您可以通过现在的测试方式轻松测试load-data
,但是可以从测试资源中传递一些test-news.edn
。无需为幸福的道路而嘲笑任何东西。
这样,您还可以针对其他情况编写测试:如果文件丢失,该怎么办?或.edn文件格式错误。如果您传递一些永久加载的资源怎么办?等