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
相关产品推荐
相关产品推荐

