如何为Assembly类的C#扩展方法编写单元测试
Assembly.GetAttribute扩展方法单元测试编写指南
这个扩展方法的逻辑分支非常简单,只需要覆盖核心场景即可,不需要构造复杂的测试桩:
核心测试场景
你需要覆盖三类逻辑分支:
- 传入的程序集标记了目标类型的特性时,方法返回第一个匹配的特性实例
- 传入的程序集没有标记目标类型的特性时,方法返回null
- 入参Assembly为null时的边界行为(当前实现未做空校验,会抛出空引用异常,你可以根据需求决定是否补充入参校验)
测试实现步骤
- 首先定义测试专用的自定义特性,避免和系统自带特性产生干扰:
// 用于标记测试程序集的特性 [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] public class TestAssemblyAttribute : Attribute { public string Marker { get; } public TestAssemblyAttribute(string marker) { Marker = marker; } } // 用于验证无标记场景的特性,不会打到测试程序集上 [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] public class NotPresentAttribute : Attribute { }
- 给测试项目标记测试用特性,可以直接写在测试项目任意代码文件的顶层,也可以写在AssemblyInfo.cs里:
[assembly: TestAssembly("测试标记值")]
- 编写测试用例,以下以xUnit为例,NUnit、MSTest的逻辑完全一致:
public class GetAttributeExtensionTests { [Fact] public void GetAttribute_WhenAssemblyHasSpecifiedAttribute_ReturnsCorrectAttributeInstance() { // 直接拿当前测试程序集作为测试载体即可,不需要动态生成程序集 Assembly currentAsm = typeof(GetAttributeExtensionTests).Assembly; var attribute = currentAsm.GetAttribute<TestAssemblyAttribute>(); Assert.NotNull(attribute); Assert.Equal("测试标记值", attribute.Marker); } [Fact] public void GetAttribute_WhenAssemblyHasNoSpecifiedAttribute_ReturnsNull() { Assembly currentAsm = typeof(GetAttributeExtensionTests).Assembly; var attribute = currentAsm.GetAttribute<NotPresentAttribute>(); Assert.Null(attribute); } [Fact] public void GetAttribute_WhenInputAssemblyIsNull_ThrowsException() { Assembly nullAsm = null; // 你当前的实现没有做空入参校验,这里会抛出NullReferenceException // 如果后续补充了@this的null校验并抛出ArgumentNullException,修改这里的断言即可 Assert.Throws<NullReferenceException>(() => nullAsm.GetAttribute<TestAssemblyAttribute>()); } }
补充说明
你当前代码里
Attribute.GetCustomAttributes的第三个参数传了false,也就是不搜索继承的特性,对于Assembly类型的特性查找来说本身不存在继承链场景,现有用例已经覆盖这个逻辑。如果需要验证多实例特性返回第一个的逻辑,可以新增一个设置AllowMultiple = true的测试特性,给程序集打多个同类型特性后,断言返回的是第一个声明的实例即可。
内容的提问来源于stack exchange,提问作者HamedFathi
相关产品推荐
相关产品推荐

