如何让指定方法仅在Unity单元测试脚本与程序集中可访问
问题根源
你之前为测试程序集添加宏定义的配置不生效,是因为被宏包裹的构造函数属于主业务代码程序集,宏条件判断发生在所属代码的编译阶段,和后续引用它的测试程序集的宏配置完全无关。主程序集编译时未定义UNITY_MACROS的话,这个构造函数会被直接裁剪,测试程序集自然无法访问。
推荐实现方案(无需宏,更稳定)
用.NET原生的InternalsVisibleTo特性实现,仅开放给指定测试程序集访问:
- 调整
MyClass代码,去掉宏包裹,将测试用构造函数改为internal修饰:
public class MyClass { public Data MyData { get; } internal MyClass() { // Complex code setting MyData } // 测试专用构造函数 internal MyClass(MyData data) { MyData = data; } }
- 在主业务程序集的任意
AssemblyInfo.cs文件中(Unity中可在Assets目录下新建该文件)添加如下配置,指定可访问internal成员的测试程序集名称:
using System.Runtime.CompilerServices; // 替换成你自己的测试程序集名称 [assembly: InternalsVisibleTo("MyTestAssemblyName")]
- (可选)避免同程序集业务代码误用测试构造函数,可以给构造函数添加过时标记,仅允许测试代码忽略警告:
[Obsolete("仅允许单元测试调用", error: true)] internal MyClass(MyData data) { MyData = data; }
测试代码调用时添加[SuppressMessage("Usage", "CS0618:成员已过时")]即可正常编译。
该方案无需处理编译宏的开关配置,生产代码中除指定测试程序集外,所有其他代码都无法访问该构造函数,完全满足需求。
备选方案(坚持用宏实现)
如果必须用宏裁剪掉生产代码中的测试构造函数,需要调整宏的配置位置:
- 不要仅给测试程序集加
UNITY_MACROS宏,需要给主业务程序集也添加该宏定义,且仅在运行测试的场景下开启,打包生产版本时移除该宏。 - Unity中可以通过主程序集的
.asmdef文件的Version Defines配置,绑定Test Framework包的存在状态自动开启宏,避免手动开关的遗漏问题。
内容的提问来源于stack exchange,提问作者fafase
相关产品推荐
相关产品推荐

