Search code examples
c#specflowscenariosobsolete

Replace ScenarioContext.Current in non binding class using context injection


I want to use context injection to remove the obsolete warnings for FeatureContext.Current and ScenarioContext.Current my code.

I have a reporter in a non binding class that requires setup before the test is run.

I have tried making a constructor and instantiating it but the values always return as Null.

In the Setup Step

namespace EclipseWebAutomationV2.Steps
{
    [Binding]
    class StepSetup
    {

        public static FeatureContext _featurecontext;
        public static ScenarioContext _scenariocontext;


        [BeforeTestRun]
        public static void InitializeReport()
        {
            Reporter.ReportInit();
        }

        [BeforeFeature]
        public static void BeforeFeature()
        {
            Reporter bfeature = new Reporter(_featurecontext, _scenariocontext);
            bfeature.ReportFeature();
        }
    }
}

In the report class:

namespace EclipseWebAutomationV2.Configurations
{
    class Reporter
    {



        private readonly FeatureContext _featurecontext;
        private readonly ScenarioContext _scenariocontext;
        public Reporter(FeatureContext _featurecontext, ScenarioContext _scenariocontext)
        {
            this._featurecontext = _featurecontext;
            this._scenariocontext = _scenariocontext;
        }

        public static void ReportInit()
        {
            //does stuff
        }


        public void ReportFeature()
        {
            featureName = extent.CreateTest<Feature>(_featurecontext.FeatureInfo.Title);
        }
    }
}

_featurecontext always returns null. I was hoping for it to get the current feature context so i can use it to get the title and use it in other parts of the reporting class.

I am having the same issue with _scenariocontext.


Solution

  • The main problem is the Reporter object requires a FeatureContext and ScenarioContext object. When the [BeforeFeature] hook is executing, the ScenarioContext does not exist yet.

    The [BeforeFeature] hook supports a couple of overloads, one of which accepts the newly created FeatureContext as an argument.

    This coupled with removing the FeatureContext and ScenarioContext objects as dependencies for the Reporter class will solve your problem.

    First, change the StepSetup class to remove the dependencies on FeatureContext and ScenarioContext, and alter the [BeforeFeature] to accept a FeatureContext object as an argument:

    [Binding]
    class StepSetup
    {
        [BeforeTestRun]
        public static void InitializeReport()
        {
            Reporter.ReportInit();
        }
    
        [BeforeFeature]
        public static void BeforeFeature(FeatureContext featureContext)
        {
            var reporter = new Reporter();
    
            reporter.ReportFeature(featureContext);
        }
    }
    

    Then change the Reporter class to accept a FeatureContext argument in ReportFeature:

    class Reporter
    {
        public static ReportInit()
        {
            // does stuff
        }
    
        public void ReportFeature(FeatureContext featureContext)
        {
            featureName = extent.CreateTest<Feature>(featureContext.FeatureInfo.Title);
        }
    }
    

    If the Reporter.ReportFeature method does not use any instance fields, consider making this method a static method as well, and using a static constructor instead of the Reporter.ReportInit() method:

    static class Reporter
    {
        static Reporter()
        {
            // does stuff
        }
    
        public static void ReportFeature(FeatureContext featureContext)
        {
            featureName = extent.CreateTest<Feature>(featureContext.FeatureInfo.Title);
        }
    }
    

    Then your StepSetup class becomes even simpler with no need to call a static "init" method on the Reporter class:

    [Binding]
    class StepSetup
    {
        [BeforeFeature]
        public static void BeforeFeature(FeatureContext featureContext)
        {
            Reporter.ReportFeature(featureContext);
        }
    }
    

    See Static Constructors (C# Programming Guide)