You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elixir用Mox测试Phoenix代码时未定义expect的测试运行报错问题

问题根因

Mox 默认采用进程隔离机制,所有桩、预期配置仅对执行配置的进程生效。你在 test_helper.exs 中执行的 stub_with 仅作用于测试启动的主进程,而每个测试用例运行在独立的子进程中,默认无法继承主进程的桩配置,因此出现未定义预期的报错。

解决方案

以下两种方案任选即可,都不需要修改现有测试逻辑:

方案1:全局开启桩配置继承(最简便)

在 test_helper.exs 中定义Mock后,新增一行Mox.allow配置允许所有子进程共享桩:

Mox.defmock(MyApplication.Accounts.MockRecaptcha, for: MyApplication.Accounts.RecaptchaBehaviour)
# 允许所有派生进程继承当前进程的Mock配置
Mox.allow(MyApplication.Accounts.MockRecaptcha, self(), :all)
Mox.stub_with(MyApplication.Accounts.MockRecaptcha, MyApplication.Accounts.Recaptcha)

该方案下自定义expect的优先级会高于全局桩,不会影响你需要校验Mock调用的测试逻辑。

方案2:全局setup钩子注入桩

如果不想开启全局共享,可以在 test_helper.exs 中配置全局测试前置钩子,每个测试启动前自动给当前进程设置桩:

ExUnit.start()

ExUnit.configure(
  setup: fn ->
    Mox.stub_with(MyApplication.Accounts.MockRecaptcha, MyApplication.Accounts.Recaptcha)
    :ok
  end
)

额外适配建议

你报错信息显示调用参数为nil,可以在你封装的Recaptcha代理模块中新增nil参数兼容逻辑,避免调用原生库时报错:

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

    # 兼容无验证码参数的测试场景,返回值可根据业务需求调整
    def verify(nil, _options) do
      {:error, :missing_captcha}
    end

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

内容的提问来源于stack exchange,提问作者silverdr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 17:06:03