# Xunit V2 Parameterised Tests ## UseParameters() `UseParameters()` controls what parameters are used when naming files. Verify.Xunit does not detect the parametrised arguments, as such `UseParameters()` is required. ### Usage: For the above scenarios where parameters are not automatically detected: ```cs [Theory] [InlineData("Value1")] [InlineData("Value2")] public Task UseParametersUsage(string arg) { var somethingToVerify = $"{arg} some text"; return Verify(somethingToVerify) .UseParameters(arg); } ``` snippet source | anchor If not all parameters are required, a subset can be passed in. In this scenario, the parameters passed in will match with the method parameter names from the start. For example the following will result in a file named `ParametersSample.UseParametersSubSet_arg1=Value1_arg2=Value2.verified.txt` ```cs [Theory] [InlineData("Value1", "Value2", "Value3")] public Task UseParametersSubSet(string arg1, string arg2, string arg3) { var somethingToVerify = $"{arg1} {arg2} {arg3} some text"; return Verify(somethingToVerify) .UseParameters(arg1, arg2); } ``` snippet source | anchor If the number of parameters passed to `UseParameters()` is greater than the number of parameters in the test method, an exception will be thrown. ### InlineData #### Instance ```cs [Theory] [InlineData("Value1")] [InlineData("Value2")] public Task InlineDataUsage(string arg) { var settings = new VerifySettings(); settings.UseParameters(arg); return Verify(arg, settings); } ``` snippet source | anchor #### Fluent ```cs [Theory] [InlineData("Value1")] [InlineData("Value2")] public Task InlineDataUsageFluent(string arg) => Verify(arg) .UseParameters(arg); ``` snippet source | anchor ### MemberData Given the following MemberData ```cs public static IEnumerable GetData() { yield return [ "Value1" ]; yield return [ "Value2" ]; } ``` snippet source | anchor #### Instance ```cs [Theory] [MemberData(nameof(GetData))] public Task MemberDataUsage(string arg) { var settings = new VerifySettings(); settings.UseParameters(arg); return Verify(arg, settings); } ``` snippet source | anchor #### Fluent ```cs [Theory] [MemberData(nameof(GetData))] public Task MemberDataUsageFluent(string arg) => Verify(arg) .UseParameters(arg); ``` snippet source | anchor ### Unknown parameter types For unknown types the parameter information cannot be derived. In these scenarios `ToString()` is used. To use custom text for a parameter use `NameForParameter()`. ```cs public class ComplexParametersSample { [ModuleInitializer] public static void Initialize() { VerifierSettings.NameForParameter(_ => _.Value); VerifierSettings.NameForParameter(_ => _.Value); } [Theory] [MemberData(nameof(GetData))] public Task ComplexMemberData(ComplexData arg) { var settings = new VerifySettings(); settings.UseParameters(arg); return Verify(arg, settings); } [Theory] [MemberData(nameof(GetData))] public Task ComplexMemberDataFluent(ComplexData arg) => Verify(arg) .UseParameters(arg); [Theory] [MemberData(nameof(GetData))] public Task ComplexMemberNullableData(ComplexData arg) { var settings = new VerifySettings(); settings.UseParameters(arg); return Verify(arg, settings); } [Theory] [MemberData(nameof(GetData))] public Task ComplexMemberNullableDataFluent(ComplexData arg) => Verify(arg) .UseParameters(arg); public static IEnumerable GetData() { yield return [ new ComplexData("Value1") ]; yield return [ new ComplexData("Value2") ]; } public record ComplexData(string Value); [Theory] [MemberData(nameof(GetStructData))] public Task ComplexMemberStructData(ComplexStructData arg) { var settings = new VerifySettings(); settings.UseParameters(arg); return Verify(arg, settings); } [Theory] [MemberData(nameof(GetStructData))] public Task ComplexMemberStructDataFluent(ComplexStructData arg) => Verify(arg) .UseParameters(arg); [Theory] [MemberData(nameof(GetStructData))] public Task ComplexMemberNullableStructData(ComplexStructData arg) { var settings = new VerifySettings(); settings.UseParameters(arg); return Verify(arg, settings); } [Theory] [MemberData(nameof(GetStructData))] public Task ComplexMemberNullableStructDataFluent(ComplexStructData arg) => Verify(arg) .UseParameters(arg); public static IEnumerable GetStructData() { yield return [new ComplexStructData("Value1")]; yield return [new ComplexStructData("Value2")]; } public record ComplexStructData(string Value); } ``` snippet source | anchor ## Overriding text used for parameters `UseTextForParameters()` can be used to override the substitution text used for the `{Parameters}` part of the file convention. ``` {Directory}/{TestClassName}.{TestMethodName}_{Parameters}_{UniqueFor1}_{UniqueFor2}_{UniqueForX}.verified.{extension} ``` The below samples produce: For the instance case: * TheTest.UseTextForParameters_Value1.verified.txt * TheTest.UseTextForParameters_Value2.verified.txt For the fluent case: * TheTest.UseTextForParametersFluent_Value1.verified.txt * TheTest.UseTextForParametersFluent_Value2.verified.txt ### Instance ```cs [Theory] [InlineData("Value1")] [InlineData("Value2")] public Task UseTextForParameters(string arg) { var settings = new VerifySettings(); settings.UseTextForParameters(arg); return Verify(arg + "UseTextForParameters", settings); } ``` snippet source | anchor ### Fluent ```cs [Theory] [InlineData("Value1")] [InlineData("Value2")] public Task UseTextForParametersFluent(string arg) => Verify(arg + "UseTextForParametersFluent") .UseTextForParameters(arg); ``` snippet source | anchor ## Ignore parameters for verified filename By default, Verify expects every parameterized case to have a unique [file name](/docs/naming.md) with the parameters appended to the file name. This behavior can be overridden by using `IgnoreParametersForVerified()`. In this case, the verified file name does not contain the parameter values, meaning it is the same for each testcase. `IgnoreParametersForVerified` accepts an array for passing through the parameters. These values are passed to [UseParameters](#UseParameters). This is required for MSTest, and xUnit. Parameters should not be passed for NUnit, TUnit and Fixie since they are automatically detected. The below samples produce: For the instance case: * NamerTests.IgnoreParametersForVerified_arg=One.received.txt * NamerTests.IgnoreParametersForVerified_arg=Two.received.txt * NamerTests.IgnoreParametersForVerified.verified.txt For the fluent case: * NamerTests.IgnoreParametersForVerifiedFluent_arg=One.received.txt * NamerTests.IgnoreParametersForVerifiedFluent_arg=Two.received.txt * NamerTests.IgnoreParametersForVerifiedFluent.verified.txt ### Instance ```cs [Theory] [InlineData("One")] [InlineData("Two")] public Task IgnoreParametersForVerified(string arg) { var settings = new VerifySettings(); settings.IgnoreParametersForVerified(arg); return Verify("value", settings); } ``` snippet source | anchor ### Fluent ```cs [Theory] [InlineData("One")] [InlineData("Two")] public Task IgnoreParametersForVerifiedFluent(string arg) => Verify("value") .IgnoreParametersForVerified(arg); ``` snippet source | anchor ## IgnoreParametersForVerified with override parameters The parameters passed to IgnoreParametersForVerified can be used pass custom parameters to [UseParameters](#UseParameters). ### Instance ```cs [Theory] [InlineData("One")] [InlineData("Two")] public Task IgnoreParametersForVerifiedCustomParams(string arg) { var settings = new VerifySettings(); settings.IgnoreParametersForVerified($"Number{arg}"); return Verify("value", settings); } ``` snippet source | anchor ### Fluent ```cs [Theory] [InlineData("One")] [InlineData("Two")] public Task IgnoreParametersForVerifiedCustomParamsFluent(string arg) => Verify("value") .IgnoreParametersForVerified($"Number{arg}"); ``` snippet source | anchor