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

如何定义可被ex_machina的params_for识别的工厂?已定义却无法找到

问题原因

测试代码仅通过use ExMachina.Ecto引入基础功能,但未关联自定义的Booking.Factory模块。ExMachina默认只会在当前测试模块内查找工厂定义,无法识别外部Booking.Factory里的practitioner_factory函数。而IEx中能正常运行,是因为你直接通过Booking.Factory.practitioner_factory!明确指定了工厂所在模块,绕过了这个匹配逻辑。

解决方法

以下三种方式任选其一即可:

方法1:在测试模块中导入Factory模块

添加import Booking.Factory,让测试模块直接调用Factory内的工厂函数:

defmodule Booking.PractitionersTest do
  use ExUnit.Case, async: true
  use Booking.DataCase
  use ExMachina.Ecto
  import Booking.Factory
  alias Ecto.Changeset
  alias Booking.Practitioners.Practitioner

  test "is valid from the factory" do
    new_practitioner = params_for(:practitioner)
    changeset = Practitioner.changeset(Practitioner, new_practitioner)
    assert changeset.valid?
  end
end

方法2:在测试模块中use自定义Factory

由于Booking.Factory已经集成了ExMachina.Ecto,测试模块可直接use Booking.Factory继承所有工厂功能:

defmodule Booking.PractitionersTest do
  use ExUnit.Case, async: true
  use Booking.DataCase
  use Booking.Factory
  alias Ecto.Changeset
  alias Booking.Practitioners.Practitioner

  test "is valid from the factory" do
    new_practitioner = params_for(:practitioner)
    changeset = Practitioner.changeset(Practitioner, new_practitioner)
    assert changeset.valid?
  end
end

方法3:调用params_for时指定工厂模块

如果不想修改测试模块的引入语句,可在调用时明确指定Factory模块:

defmodule Booking.PractitionersTest do
  use ExUnit.Case, async: true
  use Booking.DataCase
  use ExMachina.Ecto
  alias Ecto.Changeset
  alias Booking.Practitioners.Practitioner

  test "is valid from the factory" do
    new_practitioner = Booking.Factory.params_for(:practitioner)
    changeset = Practitioner.changeset(Practitioner, new_practitioner)
    assert changeset.valid?
  end
end

注:测试代码中第24行的Practitioner需要提前通过alias引入,否则会出现模块未定义错误,上述示例已补充该逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:05:36