DevD
DevD

Reputation: 51

Specflow Container of the steps class has not been initialized

public class BaseSteps : Steps
{
    [BeforeFeature]
    public static void BeforeFeatureStep()
    {
        var otherStep = new OtherStep();
        otherStep.ExecuteStep();
    }
} 

public class OtherStep : Steps
{
    public void ExecuteStep() 
    {
        var key = 'key';
        var val = 'val';
        this.FeatureContext.Add(key, val);
    }
}

This is a sample snippet. When I try to access this.FeatureContext.Add(), I get an exception stating Container of the steps class has not been initialized

Any help on this is appreciated.

Upvotes: 5

Views: 1665

Answers (1)

Andreas Willich
Andreas Willich

Reputation: 5835

The FeatureContext is not initialized, because the Step class is not resolved by the SpecFlow DI Container. So the SetObjectContainer method is not called (https://github.com/techtalk/SpecFlow/blob/master/TechTalk.SpecFlow/Steps.cs#L10).

As a general rule, you should not instantiate the steps classes on your own, but get them via Context Injection (http://specflow.org/documentation/Context-Injection).

But that is not possible in your case because you are in a BeforeFeature hook.

A possible solution would be, that you use the latest pre-release of SpecFlow (https://www.nuget.org/packages/SpecFlow/2.2.0-preview20170523). There you can get the FeatureContext via a parameter in the hook method. It looks like this:

[BeforeFeature]
public static void BeforeFeatureHook(FeatureContext featureContext)
{
    //your code
}

Your code could then look like this:

public class FeatureContextDriver
{
    public void FeatureContextChanging(FeatureContext featureContext)
    {
        var key = 'key';
        var val = 'val';
        featureContext.Add(key, val);
    }
}

[Binding]
public class BaseSteps : Steps
{
    [BeforeFeature]
    public static void BeforeFeatureStep(FeatureContext featureContext)
    {
        var featureContextDriver = new FeatureContextDriver();
        featureContextDriver.FeatureContextChanging(featureContext);
    }
} 

[Binding]
public class OtherStep : Steps
{
    private FeatureContextDriver _featureContextDriver;
    public OtherStep(FeatureContextDriver featureContextDriver)
    {
        _featureContextDriver = featureContextDriver;
    }

    public void ExecuteStep() 
    {
        _featureContextDriver.FeatureContextChanging(this.FeatureContext);
    }
}

Code is not tested/tried out and applies the Driver Pattern.


Full Disclosure: I am one of the maintainers of SpecFlow and SpecFlow+.

Upvotes: 3

Related Questions