Elixir中使用Private模块在test环境无法调用私有函数的问题
问题解决步骤
1. 修正模块中私有函数的定义方式
你在private do块里错误使用了defp,Private模块的设计逻辑是:在private do块内用def定义函数,它会自动将这些函数标记为私有,但允许测试模块合法访问。修改后的Mechanics.Servo模块代码如下:
defmodule Mechanics.Servo do require Logger use Private private do def check_head(<<>>) do Logger.debug("no data") {:error, :noData} end def check_head(<<0x1::8, 0x2::8, rest::binary>>) do {:ok, rest} end def check_head(<<_::8, rest::binary>>) do check_head(rest) end end end
2. 完善mix.exs的依赖配置
你的mix.exs中缺少Private依赖声明,需要在deps/0函数中添加该依赖:
defmodule Mechanics.MixProject do use Mix.Project def project do [ app: :mechanics, version: "0.1.0", elixir: "~> 1.13", start_permanent: Mix.env() == :test, deps: deps() ] end defp deps do [ {:private, "~> 1.0"} ] end end
添加完成后,执行命令安装依赖:
mix deps.get
3. 修正测试模块的调用方式
测试模块需要通过Private提供的宏导入目标模块的私有函数,才能正常调用。修改后的测试代码如下:
defmodule Mechanics.Test do import Private, only: [private: 1] private Mechanics.Servo def a() do Mechanics.Servo.check_head(<<0x12, 0x4c, 1, 2, 3>>) end end
报错原因说明
- 用
defp在private do块内定义函数,会让函数变成Elixir原生的私有函数,即使使用Private模块也无法外部访问。 - 缺少依赖会导致Private模块的宏无法正常工作,私有函数的访问规则没有被正确应用。
- 测试模块未导入私有函数,直接调用会触发Elixir的私有函数访问限制。
内容的提问来源于stack exchange,提问作者Chen Yu
相关产品推荐
相关产品推荐

