【问题标题】:Elixir Mox library testing Phoenix code - with no Mox expectations in some test filesElixir Mox 库测试 Phoenix 代码 - 在某些测试文件中没有 Mox 期望
【发布时间】:2021-09-30 20:56:46
【问题描述】:

TL;DR

不相关的测试失败,因为使用 Mox 库时“未定义期望”,stub_with/2 似乎没有任何帮助

详情:

有 Recaptcha 库

https://github.com/samueljseay/recaptcha

这有助于我验证 recaptcha 响应。都不错。测试时间(是的,在让代码以某种方式工作之后——向所有 TDD 粉丝道歉)。显然我不想用我的测试来打谷歌叔叔,所以:

Mox.defmock(MyApplication.Accounts.MockRecaptcha, for: MyApplication.Accounts.RecaptchaBehaviour)

test_helper.ex 内。需要单独定义该行为:

defmodule MyApplication.Accounts.RecaptchaBehaviour do
    @callback verify(String.t(), Keyword.t()) :: {:ok, Response.t()} | {:error, [atom]}
    @callback verify(String.t()) :: {:ok, Response.t()} | {:error, [atom]}
end

使用以下方法进行一些测试:

MyApplication.Accounts.MockRecaptcha
|> expect(:verify, fn _response -> {:ok, _response} end)

到目前为止一切顺利,除了...所有其他测试现在都失败了:

** (Mox.UnexpectedCallError) no expectation defined for MyApplication.Accounts.MockRecaptcha.verify/1 in process #PID<0.854.0> with args [nil]

阅读我发现的优秀文档:“[...] 当没有定义任何期望时,您可能希望实现回退到存根(或实际)实现。stub_with/2 正是您所需要的!”

所以test_helper.ex中的另一行:

Mox.stub_with(MyApplication.Accounts.MockRecaptcha, Recaptcha)

这行不通,因为** (ArgumentError) Recaptcha does not implement any behaviour,好吧.. 让我们添加我自己的“代理”,这样可以:

defmodule MyApplication.Accounts.Recaptcha do
    @behaviour MyApplication.Accounts.RecaptchaBehaviour

    def verify(response, options \\ []) do
        Recaptcha.verify(response, options)
    end
end

并将test_helper.ex 行更改为

Mox.stub_with(MyApplication.Accounts.MockRecaptcha, MyApplication.Accounts.Recaptcha)

现在ArgumentError 消失了,但所有没有 Mox 期望的测试都像以前一样失败。不管有没有stub_with/2,都没有变化。

而且我觉得我已经花了太多时间在它上面...... :-( 有什么帮助让我走上正轨吗?

更新:

根据 cmets 的要求,失败的测试例如是控制器测试:

    describe "guest GET /signup" do
        setup do
            System.put_env("RECAPTCHA_SITE_KEY", "123")
            {:ok, conn: get(build_conn(), "/signup")}
        end

        test "returns HTTP_OK", %{conn: conn} do
            assert response(conn, 200)
        end

        test "invokes UserView", %{conn: conn} do
            assert Phoenix.Controller.view_module(conn) == MyApplication.UserView
        end

        test "renders into guest layout", %{conn: conn} do
            assert Phoenix.Controller.layout(conn) == {MyApplication.LayoutView, :guest_layout}
        end

        test "renders 'new' template", %{conn: conn} do
            assert Phoenix.Controller.view_template(conn) == "new.html"
        end
    end

是的,由于生成了请求,他们(不必要地)“触摸”了 Recaptcha,这是另一回事,“解决方案”不是让他们在 Recaptcha 周围走动,而是让 stub_with/2 完成它的工作.

【问题讨论】:

  • 你能包含你的测试代码吗?很难看出这些是如何结合在一起的。你能指定你是否在异步运行测试吗? recaptcha 包确实应该允许将 HTTP 客户端指定为可选覆盖(因为它是在编译时设置的,因此几乎无法测试)。
  • 对 moxed 函数的调用是发生在与测试相同的进程中,还是在生成的进程中(任务等)?如果过程不同,这可以解释您遇到的情况吗? hexdocs.pm/mox/Mox.html#module-multi-process-collaboration 另一个原因可能是调用次数大于 1,因为默认情况下 expect) 将 n 设置为 1?
  • @Everett - 失败的测试位于单独的文件中,例如 e. G。典型的控制器测试、断言 HTTP 状态代码、渲染视图等。
  • @sabiwara - 这是一个简单的mix test,我也没有在测试文件中生成任何进程。顺便说一句 - 似乎在 elixirforum 成员的帮助下,我现在接近解决方案了
  • 在“典型控制器测试”中查看代码会很有帮助——SO 更适合评估实际代码。

标签: automated-tests elixir phoenix-framework mox


【解决方案1】:

作为 Elixir Forum 上的 discussed stub_with/2 不能像 e 那样“全局”调用。 G。来自test_helper.ex。它只能在setup 或直接在测试中调用。

【讨论】:

    猜你喜欢
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    相关资源
    最近更新 更多