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

C#单元测试:如何创建COM互操作值的测试输入?

解决方案

方法一:构造模拟对象替代IADSLargeInteger

被测方法通过反射读取HighPart和LowPart属性,不需要依赖真实的COM对象,只要构造一个包含这两个属性的普通对象即可。

方式1:自定义模拟类

public class MockLargeInteger
{
    public int HighPart { get; set; }
    public int LowPart { get; set; }
}

单元测试中使用:

public void ConvertLargeIntegerToLong_ComObjectLargeInt_Long()
{
    var expectedValue = 94294967295L;
    // 计算对应值:94294967295 = 0x15FFFFFFFF → HighPart=21,LowPart=-1(int类型的0xFFFFFFFF)
    var testValue = new MockLargeInteger
    {
        HighPart = 21,
        LowPart = -1
    };
    var result = ConvertLargeIntegerToLong(testValue);
    Assert.AreEqual(expectedValue, result);
}

方式2:用匿名类型简化

public void ConvertLargeIntegerToLong_ComObjectLargeInt_Long()
{
    var expectedValue = 94294967295L;
    var testValue = new { HighPart = 21, LowPart = -1 };
    var result = ConvertLargeIntegerToLong(testValue);
    Assert.AreEqual(expectedValue, result);
}

方法二:重构被测方法,拆分逻辑简化测试

原方法将反射获取属性与数值转换逻辑耦合,可拆分出纯转换逻辑的方法,单独测试核心计算逻辑:

public static long ConvertLargeIntegerToLong(object largeInteger)
{
    var type = largeInteger.GetType();
    var highPart = (int)type.InvokeMember("HighPart", BindingFlags.GetProperty, null, largeInteger, null)!;
    var lowPartInt = (int)type.InvokeMember("LowPart", BindingFlags.GetProperty | BindingFlags.Public, null, largeInteger, null)!;
    // 把转换逻辑提取为独立方法
    return ConvertHighLowToLong(highPart, lowPartInt);
}

public static long ConvertHighLowToLong(int highPart, int lowPartInt)
{
    uint lowPartUint;
    unchecked
    {
        lowPartUint = (uint)lowPartInt;
    }
    return (long)highPart << 32 | (long)lowPartUint;
}

针对提取出的方法编写全面测试:

[Test]
public void ConvertHighLowToLong_VariousCases_ReturnsCorrectValue()
{
    // 测试目标值案例
    Assert.AreEqual(94294967295L, ConvertHighLowToLong(21, -1));
    // 正数LowPart案例
    Assert.AreEqual(12345L, ConvertHighLowToLong(0, 12345));
    // 负数HighPart案例
    Assert.AreEqual(-4294967296L, ConvertHighLowToLong(-1, 0));
    // 零值案例
    Assert.AreEqual(0L, ConvertHighLowToLong(0, 0));
}

额外说明

如果一定要模拟真实的COM对象,可以通过Type.GetTypeFromCLSID获取IADSLargeInteger类型并创建实例,但这种方式依赖Active Directory环境,不符合单元测试“无外部依赖”的原则,不推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:01:22