Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when injecting ScenarioContext in .NET Framework 4.8 #12

Open
grootstebozewolf opened this issue Apr 13, 2021 · 2 comments
Open

Comments

@grootstebozewolf
Copy link

Steps to reproduce

Create a .Net Framework test project (MSBuild)

Added the following packages:
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="BoDi" version="1.4.1" targetFramework="net48" />
  <package id="Cucumber.Messages" version="6.0.1" targetFramework="net48" />
  <package id="Gherkin" version="6.0.0" targetFramework="net48" />
  <package id="Google.Protobuf" version="3.7.0" targetFramework="net48" />
  <package id="MSTest.TestAdapter" version="2.1.2" targetFramework="net48" />
  <package id="MSTest.TestFramework" version="2.1.2" targetFramework="net48" />
  <package id="SimpleInjector" version="5.3.0" targetFramework="net48" />
  <package id="SpecFlow" version="3.1.80" targetFramework="net48" />
  <package id="SpecFlow.MsTest" version="3.1.80" targetFramework="net48" />
  <package id="SpecFlow.SimpleInjector" version="2.0.0" targetFramework="net48" />
  <package id="SpecFlow.Tools.MsBuild.Generation" version="3.1.80" targetFramework="net48" />
  <package id="System.IO" version="4.3.0" targetFramework="net48" />
  <package id="System.Net.Http" version="4.3.4" targetFramework="net48" />
  <package id="System.Reflection.Emit" version="4.3.0" targetFramework="net48" />
  <package id="System.Reflection.Emit.Lightweight" version="4.3.0" targetFramework="net48" />
  <package id="System.Runtime" version="4.3.0" targetFramework="net48" />
  <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net48" />
  <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net48" />
  <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net48" />
  <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net48" />
  <package id="System.Threading.Tasks.Extensions" version="4.4.0" targetFramework="net48" />
  <package id="System.ValueTuple" version="4.4.0" targetFramework="net48" />
  <package id="Utf8Json" version="1.3.7" targetFramework="net48" />
</packages>

Ammended the app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="BoDi" publicKeyToken="ff7cd5ea2744b496" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.4.0.0" newVersion="1.4.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="SimpleInjector" publicKeyToken="984cb50dea722e99" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Created a simple test feature file and implemented the steps, then created a step implementation where I inject the scenarioContext:

using System;
using TechTalk.SpecFlow;

namespace Example
{
    [Binding]
    public class ExampleSteps
    {
        private readonly ScenarioContext scenarioContext;

        public PermissiesSteps(ScenarioContext scenarioContext)
        {
            this.scenarioContext = scenarioContext;
        }

        [Given(@"some given step")]
        public void SomeGivenStep()
        {
            scenarioContext.Pending();
        }        
    }
}

Bound the container in a TestDependencies support class

using SimpleInjector;
using SpecFlow.SimpleInjector;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Example
{
    public static class TestDependencies
    {
        [ScenarioDependencies]
        public static Container CreateContainerBuilder()
        {
            // create empty container
            var builder = new Container();

            //TODO: add customizations, stubs required for testing

            return builder;
        }
    }
}
@grootstebozewolf
Copy link
Author

Error:

Message: 
    Test method Example.Features.SomeGivenStep threw exception: 
    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.MissingFieldException: Field not found: 'SimpleInjector.Lifestyle.Singleton'.
  Stack Trace: 
    SimpleInjectorPlugin.RegisterSpecFlowDependencies(IObjectContainer objectContainer, Container container)
    <>c__DisplayClass1_0.<Initialize>b__2()
    --- End of inner exception stack trace ---
    RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
    RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
    Delegate.DynamicInvokeImpl(Object[] args)
    ObjectContainer.InvokeFactoryDelegate(Delegate factoryDelegate, ResolutionList resolutionPath, RegistrationKey keyToResolve) line 827
    FactoryRegistration.Resolve(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath) line 411
    ObjectContainer.ResolveObject(RegistrationKey keyToResolve, ResolutionList resolutionPath) line 779
    ObjectContainer.Resolve(Type typeToResolve, ResolutionList resolutionPath, String name) line 698
    ObjectContainer.Resolve[T](String name) line 673
    ObjectContainer.Resolve[T]() line 666
    SimpleInjectorTestObjectResolver.ResolveBindingInstance(Type bindingType, IObjectContainer scenarioContainer)
    lambda_method(Closure , IContextManager )
    BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration) line 69
    TestExecutionEngine.ExecuteStepMatch(BindingMatch match, Object[] arguments) line 517
    TestExecutionEngine.ExecuteStep(IContextManager contextManager, StepInstance stepInstance) line 422
    TestExecutionEngine.OnAfterLastStep() line 203
    TestRunner.CollectScenarioErrors() line 59
    ExampleFeature.ScenarioCleanup()
    ExampleFeature.SomeGivenStep() line 6

@grootstebozewolf
Copy link
Author

Tried to upgrade to the latest versions of SpecFlow and SimpleInjector.

Ammended the Example project

using SimpleInjector;
using SpecFlow.SimpleInjector;

namespace MyCalculator.Specs.Support
{
    public static class TestDependencies
    {
        [ScenarioDependencies]
        public static Container CreateContainerBuilder()
        {
            // create container with the runtime dependencies
            var builder = Dependencies.CreateContainerBuilder();
            builder.Options.ResolveUnregisteredConcreteTypes = true;

            //TODO: add customizations, stubs required for testing

            return builder;
        }
    }
}

After this, the teardown gave this error:

 AddTwoNumbers
   Source: Addition.feature line 7
   Duration: 2 min

  Message: 
    TestCleanup method MyCalculator.Specs.Features.AdditionFeature.TestTearDown threw exception. System.InvalidOperationException: System.InvalidOperationException: Collection was modified; enumeration operation may not execute..
  Stack Trace: 
    ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
    Enumerator.MoveNext()
    <OfTypeIterator>d__95`1.MoveNext()
    WhereEnumerableIterator`1.MoveNext()
    ObjectContainer.Dispose()
    InternalContextManager`1.DisposeInstance()
    InternalContextManager`1.Cleanup()
    ContextManager.CleanupScenarioContext()
    TestExecutionEngine.OnScenarioEnd()
    TestRunner.OnScenarioEnd()
    AdditionFeature.TestTearDown()

And additional info:

-> Loading plugin C:\Users\_behbloemscheerj\Source\Repos\SpecFlow.SimpleInjector\sample\MyCalculator\MyCalculator.Specs\bin\Debug\net48\SpecFlow.SimpleInjector.SpecFlowPlugin.dll
-> Loading plugin C:\Users\_behbloemscheerj\Source\Repos\SpecFlow.SimpleInjector\sample\MyCalculator\MyCalculator.Specs\bin\Debug\net48\TechTalk.SpecFlow.MSTest.SpecFlowPlugin.dll
-> Loading plugin C:\Users\_behbloemscheerj\Source\Repos\SpecFlow.SimpleInjector\sample\MyCalculator\MyCalculator.Specs\bin\Debug\net48\MyCalculator.Specs.dll
-> Missing [assembly:RuntimePlugin] attribute in MyCalculator.Specs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null. Please check https://go.specflow.org/doc-plugins for details.
-> Using specflow.json
Given I have entered 50 into the calculator
-> done: CalculatorSteps.GivenIHaveEnteredIntoTheCalculator(50) (0.4s)
And I have entered 70 into the calculator
-> done: CalculatorSteps.GivenIHaveEnteredIntoTheCalculator(70) (0.0s)
When I press add
-> done: CalculatorSteps.WhenIPressAdd() (0.0s)
Then the result should be 120 on the screen
-> done: CalculatorSteps.ThenTheResultShouldBeOnTheScreen(120) (72.7s)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant