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

In case of optional parameter get error of "Parameter count mismatch" #509

Open
zsbolgar opened this issue Feb 28, 2025 · 16 comments · May be fixed by #508
Open

In case of optional parameter get error of "Parameter count mismatch" #509

zsbolgar opened this issue Feb 28, 2025 · 16 comments · May be fixed by #508
Assignees

Comments

@zsbolgar
Copy link

zsbolgar commented Feb 28, 2025

Used Visual Studio

Visual Studio 2022 + NUnit

Are the latest Visual Studio updates installed?

Yes

Content of reqnroll.json (if present)

{
  "$schema": "https://schemas.reqnroll.net/reqnroll-config-latest.json",

  "bindingAssemblies": [
    {
      "assembly": "StudioManagerCommonSteps"
    }
  ]
}

Issue Description

Step with optional parameter gives error if I call without the optional parameter.

Steps to Reproduce

I use optional parameter in several steps, eg: "^the Show User Properties checkbox is( not)? selected$"
The step method has paramter (string selected)

In case if I call without the optional parameter I get this error.

Reqnroll.BindingException : Parameter count mismatch! The binding method 'Studio.StudioManager.StudioManagerForPetrelTests:StudioManagerForPetrelTests.Features.DataTable.DataTableSteps.GivenTheCheckboxIsNotSelectedInTheDataTable(String)' should have 0 parameters
   at Reqnroll.Infrastructure.TestExecutionEngine.<GetExecuteArgumentsAsync>d__61.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Reqnroll.Infrastructure.TestExecutionEngine.<ExecuteStepAsync>d__56.MoveNext()
   at Reqnroll.Infrastructure.TestExecutionEngine.<OnAfterLastStepAsync>d__38.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Reqnroll.TestRunner.<CollectScenarioErrorsAsync>d__16.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at StudioManagerForPetrelTests.Features.DataTable.VerifyDataTableFilteringAndSortingFeaturesFeature.<ScenarioCleanupAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at StudioManagerForPetrelTests.Features.DataTable.VerifyDataTableFilteringAndSortingFeaturesFeature.<DataTableFilteringWithUserDefinedAttributes>d__11.MoveNext() in C:\Projects\SLB-OCT\DevOpsTools-QATestSpecflowUITest\Studio\StudioManagerForPetrelTests\Features\DataTable\DataTableFilteringSorting.feature:line 27
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter`1.GetResult()
   at NUnit.Framework.Internal.AsyncToSyncAdapter.Await[TResult](Func`1 invoke)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.RunTestMethod(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)

Link to a project repository that reproduces the issue

No response

@304NotModified
Copy link
Contributor

304NotModified commented Feb 28, 2025

Is this during execution or design time in VS2022?

And NUnit right?

Related code for this:

throw _errorProvider.GetParameterCountError(match, match.Arguments.Length);

@zsbolgar
Copy link
Author

zsbolgar commented Feb 28, 2025

It's during the test execution and yes, NUnit
I'm doing the migration from SpecFlow (3.9.74). There was no error during the test run.

@304NotModified 304NotModified transferred this issue from reqnroll/Reqnroll.VisualStudio Feb 28, 2025
@304NotModified
Copy link
Contributor

304NotModified commented Feb 28, 2025

It looks like optional parameters aren't supported in Reqnroll.

I will test with SpecFlow to be sure

@304NotModified
Copy link
Contributor

I'm not sure why you don't got an error with SpecFlow, but I get this with SpecFlow 3.9.74

TechTalk.SpecFlow.BindingException : Parameter count mismatch! The binding method 'TestMethod(Int32, String)' should have 1 parameters
   at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.GetExecuteArguments(BindingMatch match)
   at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStep(IContextManager contextManager, StepInstance stepInstance)
   at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnAfterLastStep()
   at TechTalk.SpecFlow.TestRunner.CollectScenarioErrors()

@304NotModified
Copy link
Contributor

This is a documentation issue.

I've created a feature request for this, see: https://github.com/orgs/reqnroll/discussions/510

I will update the docs

@304NotModified 304NotModified self-assigned this Feb 28, 2025
@olegKoshmeliuk
Copy link
Member

olegKoshmeliuk commented Feb 28, 2025

Now Reqnroll doesn't support optional parameters,
you can bring old behavior by overriding MatchArgumentCalculator ref PR #243
Plugin to bring old behavior.

public class RegexOptionalGroups : IRuntimePlugin
{
    public void Initialize(RuntimePluginEvents runtimePluginEvents, RuntimePluginParameters runtimePluginParameters,
        UnitTestProviderConfiguration unitTestProviderConfiguration)
    {
        runtimePluginEvents.CustomizeGlobalDependencies += RuntimePluginEvents_CustomizeGlobalDependencies;
    }

    private void RuntimePluginEvents_CustomizeGlobalDependencies(object sender, CustomizeGlobalDependenciesEventArgs e)
    {
        e.ObjectContainer.RegisterTypeAs<MyMatchArgumentCalculator, IMatchArgumentCalculator>();
    }

    public class MyMatchArgumentCalculator : IMatchArgumentCalculator
    {
        public object[] CalculateArguments(Match match, StepInstance stepInstance,
            IStepDefinitionBinding stepDefinitionBinding)
        {
            var regexArgs = match.Groups.Cast<Group>().Skip(1);
            if (stepDefinitionBinding.ExpressionType == "CucumberExpression")
            {
                regexArgs = regexArgs.Where(g => g.Success);
            }

            List<object> arguments = regexArgs.Select(g => g.Value).Cast<object>().ToList();
            if (stepInstance.MultilineTextArgument != null)
            {
                arguments.Add(stepInstance.MultilineTextArgument);
            }

            if (stepInstance.TableArgument != null)
            {
                arguments.Add(stepInstance.TableArgument);
            }

            return arguments.ToArray();
        }
    }
}

@gasparnagy maybe I add docs page for this case? like we have for forcing regex step def

@304NotModified 304NotModified linked a pull request Feb 28, 2025 that will close this issue
@304NotModified
Copy link
Contributor

304NotModified commented Feb 28, 2025

Plugin to bring old behavior.

@olegKoshmeliuk
I tested it locally and also I get an error with SpecFlow? So was this really working with SpecFlow?

@olegKoshmeliuk
Copy link
Member

olegKoshmeliuk commented Feb 28, 2025

Yes in SecFlow 3.x.
optional group was in regex. Method was called with all parameters. optional regex group was getting null value.
#238
Given Run within 20 seconds
Given Run

[Binding]
public sealed class CalculatorStepDefinitions
{
    [Given(@"Run(| within (\d+) seconds)")]
    public void ThenCalledApiHasFollowingResponse(string _, int? seconds)
    {
         seconds ??= 20;
         Console.WriteLine(seconds);
    }
}

@olegKoshmeliuk
Copy link
Member

@zsbolgar also other example of plugin #181 (comment)

@zsbolgar
Copy link
Author

@olegKoshmeliuk sorry, does it mean, that there will be no solution/fix in reqnroll?

@olegKoshmeliuk
Copy link
Member

@zsbolgar solution is add IMatchArgumentCalculator plugin to your solution, it will fix your steps.

@zsbolgar
Copy link
Author

thanks @olegKoshmeliuk. Is there a place where I can find how to add this kind of plugin to the solution?

@304NotModified
Copy link
Contributor

@olegKoshmeliuk the optional parameter case should look like this?
And that doesn't work in SpecFlow?

    public void ThenCalledApiHasFollowingResponse(string _, int seconds = 20)
    {
         Console.WriteLine(seconds);
    }

@olegKoshmeliuk
Copy link
Member

@zsbolgar it's simple CS file in project
don't forget add [assembly:RuntimePlugin(typeof(Plugin))]
example doc for regex plugin https://docs.reqnroll.net/latest/guides/how-to-configure-cucumber-expression-behavior.html

@304NotModified
Copy link
Contributor

thanks @olegKoshmeliuk. Is there a place where I can find how to add this kind of plugin to the solution?

See also https://docs.reqnroll.net/latest/extend/plugins.html

@zsbolgar
Copy link
Author

Thank you @olegKoshmeliuk and @304NotModified, I'm going to check it.

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

Successfully merging a pull request may close this issue.

3 participants