Umbrella项目运行控制器测试时argon2_elixir加载失败问题求助
你遇到的这个情况很典型——Umbrella项目在运行时(Postman调用API)完全正常,但测试环境下argon2_elixir的NIF模块加载失败。这大概率和测试环境的依赖编译、应用启动逻辑或者环境配置差异有关,下面是一步步的排查和解决方法:
1. 彻底重新编译所有依赖(最常见的修复手段)
Umbrella项目的依赖有时候会因为环境差异(比如测试和运行时用了不同的Erlang/Elixir版本)导致NIF编译不完整。先在项目根目录执行以下命令彻底重建依赖:
mix deps.clean --all mix deps.get mix compile
完成后再运行测试mix test,看看问题是否解决。
2. 确认DB应用的依赖配置正确
因为密码哈希逻辑在DB应用里,要确保argon2_elixir是DB应用mix.exs的直接依赖,且没有只限定在特定环境(比如只在:dev或:prod生效):
# apps/db/mix.exs defp deps do [ {:argon2_elixir, "~> 2.4"}, {:ecto_sql, "~> 3.0"}, # 其他依赖... ] end
如果之前只把argon2放在根目录的mix.exs,虽然运行时能共享依赖,但测试时Web应用的测试进程可能没有正确关联DB应用的依赖链,导致NIF模块没被编译加载。
3. 验证测试环境的Erlang版本
错误提示明确要求Erlang 20+,请确认测试环境用的Erlang版本和你运行Postman时的版本一致:
erl -version
如果测试环境用的是旧版本,升级Erlang后重新编译依赖即可。另外,确保你的系统有C编译器(比如GCC或Clang)——不过运行时正常说明编译器是具备的,大概率只是测试环境编译环节出了问题。
4. 确保测试时DB应用正确启动
Umbrella项目的测试如果只启动Web应用,可能不会自动启动DB应用及其依赖。可以在Web应用的测试用例里,添加启动DB应用的逻辑:
# apps/metricus_web/test/metricus_web/controllers/user_controller_test.exs setup do # 确保DB应用和它的所有依赖都启动 Application.ensure_all_started(:db) {:ok, conn: Phoenix.ConnTest.build_conn()} end
或者检查你的ConnCase是否已经配置了自动启动Umbrella下的所有应用。
5. 检查测试环境的argon2配置
看看config/test.exs(或DB应用的config/test.exs)里有没有异常的argon2配置,比如是否误禁用了NIF:
# 请勿设置这类配置,除非你明确知道用途 # config :argon2_elixir, :nif, false
如果有类似配置,注释掉后重新编译测试即可。
为什么Postman正常但测试失败?
运行时(比如mix phx.server)会启动Umbrella下的所有应用,依赖会被完整编译和加载;但测试时默认可能只启动当前测试的应用(Web),如果没有正确关联DB应用的依赖,就会导致argon2的NIF模块没有被编译或加载,从而抛出错误。
按照上面的步骤一步步排查,应该能解决问题。
内容的提问来源于stack exchange,提问作者Driky

