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模拟库,但我发现我很少需要它们。

by
小心,`with-redefs` 不是线程安全的。如果你并发运行测试,你将会得到疯狂的结果 :)
0
by

模拟 M 函数是测试 A 函数(你假定它会调用函数 M),在存在特别替换的函数 M 的情况下?

但假定 A 调用 M 并非十分优雅。相反,如果 A 调用了一些值得模拟的特征,可以将 M 作为参数传递给 A。(换句话说,使 A 调用的函数成为 A 的参数。)使特性具有显而易见的可替换性。

Stuart Sierra 的 "component" 或相似的纪律是完成这一目标的狡猾、隐蔽、灵巧的方式。它会连接程序的功能,例如在您的案例中是互联网。实际上,它完成了一项类似于“依赖注入”的工作。你的测试会注入模拟的互联网,你的操作模式会注入真实的互联网。

...