2024年Clojure调查中分享您的想法!

欢迎!请在关于页面查看 hakkında页以了解更多关于如何使用此功能的信息。

+1
其他

在我的应用程序中,我想模拟REST调用可能返回的每一种可能的响应。这不仅是为了测试,也是为了演示应用程序运行时的不同行为。
例如,我有这样一个需求,我的前端要对后端进行健康检查,如果它失败,它会显示一个消息,说明没有可用的服务。我现在想要一个总是失败的模拟健康检查,以便我可以演示该消息。
我想到了三种方法。

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

有人对这些方法的某些经验吗?如果有,每个方法的优缺点是什么?我是不是错过了什么?

2 个回答

+1
by

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

在您的方案中,意味着您将有一个函数,它接收表示失败的对象,并且(直接或间接)显示消息。

最好,该函数只做一件事:获取一个错误对象,返回一个效果(或分派一个事件)。

现在您不需要模拟任何东西,只需使用健康检查的正常结果和一个错误结果运行测试,并检查结果。

还有神奇的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

测试函数 A 的 M 模拟,假设 A 调用函数 M,在一个特殊替换的函数 M 存在的情况下?

但假设 A 调用 M 并不是特别优雅。相反,如果您想模拟 A 调用的某项功能,那么将 M 作为参数传递给 A。(换句话说,使 A 调用的函数成为一个参数。)确保这个特性易于替换。

要实现这一点的一种巧妙、隐蔽、灵活的方式是使用 Stuart Sierra 的 "component",或者应用类似的纪律,连接程序的功能,例如在您的情况下是互联网。实际上,它实现了类似 "依赖注入" 的功能。您的测试会注入模拟互联网,您的运营模式会注入真实互联网。

...