使用反射获取类构造函数的参数

4

我正在为一个类编写单元测试,并且希望在检查每个参数是否为空时拥有单独的异常消息。

但我不知道如何实现下面的GetParameterNameWithReflection方法:

public class struct SUT
{
    public SUT(object a, object b, object c)
    {
        if (a == null)
        {
            throw new ArgumentNullException(nameof(a));
        }

        // etc. for remaining args

        // actual constructor code
    }    
}

[TextFixture]
public class SutTests
{
    [Test]
    public void constructor_shouldCheckForFirstParameterNull()
    {
        var ex = Assert.Throws<ArgumentNullException>(new Sut(null, new object(), new object()));

        string firstParameterName = GetParameterNameWithReflection(typeof(SUT);)

        Assert.AreEqual(firstParameterName, ex.ParamName);
    }
}

作为奖励,非常欢迎对这种测试的适用性进行评论!

这个单元测试的目的是为了防止未来发生什么事情? - Damien_The_Unbeliever
@Damien_The_Unbeliever 嗯,那就是百万美元的问题。我一直在努力找到好的测试方法,最终目标是“完全采用TDD”,但这种类型的问题实际上会导致相当多的分析瘫痪。事实是:目前我只是感觉有必要进行这些测试,但我完全不确定“为什么”...也就是说,目前我没有一个像样的回答你的问题,我想 :o( - heltonbiker
这种类型的测试最常见的维护错误是“他们重命名了参数,但忘记在异常消息中更新文字”,但你已经通过使用 nameof 来防范了这种情况。 - Damien_The_Unbeliever
2个回答

6
如何呢:
static string GetFirstParameterNameWithReflection(Type type)
{
    return type.GetConstructors().Single().GetParameters().First().Name;
}

这个断言表明该类只有一个构造函数,获取参数,然后确认至少有一个这样的参数并返回名称。


赶我之前做到了 :-) - Slappywag
@Ipsit 无论你对这个名称有什么想法(编辑):它是基于问题中的代码。 - Marc Gravell

2

此方法将返回第一个构造函数的第一个参数名称。您可以扩展此方法以处理多个构造函数和不同的参数。它使用ParameterInfo类。

    public string GetFirstParameterNameWithReflection(Type t)
    {
        return t.GetConstructors()[0].GetParameters()[0].Name;
    }

@Ipsit 无论你对这个名称有什么想法(编辑):它是基于问题中的代码。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接