2

TestContext.CurrentContext.Test has several properties like FullName which can be parsed to get the current test method within NUnit. However, these don't help at all when the test's name is overridden using the TestName property on the TestCase attribute.

Is there a simple way to get the MethodInfo for the current test method from within an NUnit test? I can't simply use a stack trace, because I need this information in SetUp and TearDown when the test method is not on the stack.

I'm using NUnit 2.6.2

ChaseMedallion
  • 20,860
  • 17
  • 88
  • 152

2 Answers2

0

One thing that comes to my mind is writing a custom NUnit EventListener addin.

Then you could hook into the runcycle of the test runner and at least on the TestStarted overload you will have the TestName object. This won't have the MethodInfo available directly, but you may get it by playing around with the given properties there.

Good luck!

Dio F
  • 2,458
  • 1
  • 22
  • 39
  • Unfortunately, the link you sent says that EventListeners are invoked asynchronously and thus can't affect the test. Thus, it seems like once I'm inside a test I can't use this method to get the current test method. – ChaseMedallion Oct 04 '13 at 12:18
  • It is invoked _before_ each test is run. Then you could store the information you need - say in a static variable - and consume it _in_ the test. – Dio F Oct 04 '13 at 16:18
0

NUnit by default does not provide such information - but it can be queries via private fields and properties. Following code could be used for example (Tested with NUnit 3.13.2):

    /// <summary>
    /// Accesses private class type via reflection.
    /// </summary>
    /// <param name="_o">input object</param>
    /// <param name="propertyPath">List of properties in one string, comma separated.</param>
    /// <returns>output object</returns>
    object getPrivate(object _o, string propertyPath)
    {
        object o = _o;
        var flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
        
        foreach (var name in propertyPath.Split('.'))
        {
            System.Type type = o.GetType();

            if (char.IsUpper(name[0]))
                o = type.GetProperty(name, flags).GetValue(o);
            else
                o = type.GetField(name, flags).GetValue(o);
        }

        return o;
    }

    [SetUp]
    public void EachSpecSetup()
    {
        var mi = (MemberInfo)getPrivate(TestContext.CurrentContext.Test, "_test.Method.MethodInfo");
        // Alternative method - using Exposed nuget package:
        //dynamic test = Exposed.From(TestContext.CurrentContext.Test)._test;
        //dynamic method = Exposed.From(test)._method;
        FactAttribute attr = mi.GetCustomAttribute<FactAttribute>();
        string path = attr.FilePath;
        string funcName = attr.FunctionName;
    }

Like mentioned in code above it's also possible to use Exposed.From - but main example should be theoretically faster.

Code will throw exception if any field / property is not valid - and this is intentional - use Visual studio watch window to identify type / field / properties.

TarmoPikaro
  • 4,723
  • 2
  • 50
  • 62