2024 Clojure状态调查!中分享您的想法。

欢迎!请查看关于页面以了解此工作方式的相关更多信息。

+1
其他

在应用程序中,我想模拟REST调用可能返回的每种可能的响应。这不仅是为了测试,而且还想展示应用程序运行时的不同行为。
例如,我有一个需求,我的前端需要对后端进行健康检查,如果失败,将显示一条没有服务可用的信息。我现在想创建一个总是失败的模拟健康检查,以便我可以展示这个消息。
我思考了三种方法。

  1. 协议
  2. 不同的源路径
  3. 高阶函数

有人对这些有经验吗?如果有,有哪些优点/缺点?我遗漏了什么?

2条答案

+1

您尝试以这种方式构建应用程序,使得模拟很少需要,即您的函数大多是纯函数。

在您的例子中,这意味着您有一个函数接受表示失败的节点,并允许该函数直接或间接显示消息。

理想情况下,该函数只做一件事:获取失败对象,返回效果(或分发事件).

现在您不需要进行模拟,只需用正常的健康检查结果和失败结果运行测试并检查结果。

还有神奇的with-redef宏,允许您临时重新绑定东西。
在这个例子中,http/post已经被重新定义了

(deftest is-a-macro
  (with-redefs [http/post (fn [url] {:body "Goodbye world"})]
    (is (= {:body "Goodbye world"} (http/post "http://service.com/greet")))))

这通常就是您所需要的。
当然,您可以使用各种Java模拟库,但我发现我很少需要它们。

{name}
请注意,`with-redefs` 不是线程安全的。如果您并发运行测试,您将获得疯狂的结果 :)
0 投票
{name}

模拟函数M是测试函数A,你假设它在特殊替换的函数M的存在下调用函数M?

但是,A调用M的假设并不非常优雅。相反,如果A调用了足够重要到值得模拟的功能,将M作为参数传给A。(换句话说,使A调用的函数成为A的参数。)使该特性公开可替换。

通过使用Stuart Sierra的"component"或应用类似的纪律,以一种狡猾、不引人注目、灵活的方式完成这项任务,将程序的设施连接起来,例如在您的情况下连接互联网。实际上,它实现了类似“依赖注入”的功能。您的测试将注入模拟互联网,您的运营模式将注入真实互联网。

...