Midje:如何为单个实际值应用多个箭头断言函数
解决Midje测试中多断言复用同一目标值的问题
你遇到的问题其实是Midje的语法解析规则导致的:在单个fact里直接连续写多个箭头断言时,只有第一个=>会绑定前面的目标值,后面的=not=>因为没有关联到目标,相当于没有执行实际的断言逻辑,所以不管你怎么改后面的条件,测试都会通过。
针对这个场景,Clojure(Midje)的惯用解决方式有两种,按推荐程度排序:
1. 用facts包裹多个独立断言(简洁直观)
如果目标值比较简单,直接在facts(注意是复数)下写多个断言,每个断言都明确指向目标值。这种方式可读性最高,也是Midje推荐的写法:
(deftest test-test (facts "some-fact" {:a 1 :b 2} => (contains {:a odd?}) {:a 1 :b 2} =not=> (contains {:a even?})))
2. 用let封装目标值(避免重复代码)
如果目标值是复杂计算的结果(比如函数调用、大型数据结构),不想重复写,可以在facts内部用let定义一次,然后在多个断言里复用:
(deftest test-test (facts "some-fact" (let [test-data {:a 1 :b 2}] test-data => (contains {:a odd?}) test-data =not=> (contains {:a even?}))))
为什么不推荐用def?
新手容易想到用全局def来定义目标值,但测试里尽量避免全局变量——全局状态会让测试变得脆弱,比如不同测试用例之间可能互相干扰,而且不符合Clojure推崇的纯函数、无副作用的测试原则。
验证效果
用上面的写法修改后,你把=not=>里的even?改成odd?,测试就会失败,完全符合预期逻辑。
内容的提问来源于stack exchange,提问作者Michal M
相关产品推荐
相关产品推荐

