如何在控件进入方法之前在 base class 中获取 xunit 测试方法名称?

How to get xunit test method name in base class even before the control goes to the method?

我想在库class中找到测试方法名。

这是我的用例

public class TestClass : Base
{
    [Fact]
    public void TestMehthod()
    {
    }
}

public class Base
{
    public Base()
    {
        Console.WriteLine("Test method name is "+); // how to get test method     name here.
    }
}

尝试这样的事情:

public class Base
{
    public Base()
    {
        string methodName = this.GetType().GetMethods()
                                          .Where(m => m.GetCustomAttributes<FactAttribute>().Any())
                                          .Select(m => m.Name)
                                          .FirstOrDefault();
        Console.WriteLine("Test method name is " + methodName); // how to get test method     name here.
    }
}

编辑:

xUnit 具有属性挂钩的概念,它在测试前后 运行ning。 如果您想在 运行 时知道方法的名称 - 您可以创建将其输出到控制台的属性:

public class MethodNameToConsoleAttribute : BeforeAfterTestAttribute
{
    public override void Before(MethodInfo methodUnderTest)
    {
        Console.WriteLine("Test method name is " + methodUnderTest.Name);
    }
}

然后把它放在你的底座上class:

[MethodNameToConsole]
public class Base
{
   ...
}

编辑 2:

好的,现在我明白你想要实现什么了。 我必须说目前 xUnit 不提供任何正常的方式来做到这一点。然而,它有另一个名为 ITestOutputHelper 的概念,它允许您将输出添加到 xUnit 的。在版本 2 中,xUnit 团队只有这个接口的一个实现,称为 TestOutputHelper,它包含一个 ITest 类型的私有字段。

在这种特殊情况下,我们可以进行黑客攻击以检索私有成员,然后从中测试方法名称。它看起来像这样:

public class Base
{
    public Base(ITestOutputHelper testOutputHelper)
    {
        var helper = (TestOutputHelper)testOutputHelper;

        ITest test = (ITest)helper.GetType().GetField("test", BindingFlags.NonPublic | BindingFlags.Instance)
                                  .GetValue(helper);

        testOutputHelper.WriteLine("Test method name is " + test.TestCase.TestMethod.Method.Name);
    }
}

但是 我不建议您放弃它,因为它的实施细节将来可能会发生变化。

我宁愿在 Github 上创建一个问题来指定您需要的这种特殊情况。 xUnit 是开源项目,您可以随时写信给它的开发者。

创建一个 Xunit 测试 class 构造函数,并用 ITestOutputHelper 注入它可以帮助您在代码 运行 之前提取测试方法名称。奇怪的是,这个测试 class 构造函数会在每个测试方法之前 运行 on,你可以用它来准备你的资产,如果你注入 ITestOutputHelper (无需其他注册)。

在您的测试 class 构造函数中,您可以执行类似的操作,将测试方法名称添加为 class 成员(每个测试方法都是新的...)

另外请注意,Console.Writeline() 在 Xuint 上下文中不起作用,但您可以使用我们为此注入的相同助手!

public class TestClass : Base
{
    public TestClass(ITestOutputHelper helper):Base(helper)
    {
    }
}
...

public class Base
{
    public Base(ITestOutputHelper helper)
    {
        var type = helper.GetType();
        var testMember = type.GetField("test", BindingFlags.Instance | BindingFlags.NonPublic);
        var testMethodName = ((ITest)testMember.GetValue(helper)).DisplayName;
        helper.WriteLine("Test method name is "+testMethodName);
//
    }
}

如果你在多个地方需要测试方法,你可以创建一个 ITestOutputHelper 扩展方法并在它自己的对象上使用它:

        public static string GetTestName(this ITestOutputHelper helper)
        {
            var type = helper.GetType();
            var testMember = type.GetField("test", BindingFlags.Instance | BindingFlags.NonPublic);
            return ((ITest)testMember.GetValue(helper)).DisplayName;
        }

然后调用helper.GetTestName()