I have these lines in multiple test methods. Now, trying to create a private method to clean up but not sure how to do it. Any suggestion or pointer would be really helpful. Thanks.
var actualValiationString = string.Empty;
void messageBuilder(string validationString)
=> actualValiationString = validationString;
var validationDelegate = new Action<string>(messageBuilder);
Here's the real test methods look like:
[Theory]
[MemberData(nameof(TryGetBoolTestData))]
public void TryGetBoolShouldReturnBool(
Dictionary<string,string> metadata,
bool expectedValue,
string expectedValidationString
)
{
var actualValiationString = string.Empty;
void messageBuilder(string validationString)
=> actualValiationString = validationString;
var validationDelegate = new Action<string>(messageBuilder);
DictionaryExtensions.TryGetBool(
metadata,
MetadataKey,
out var response,
validationDelegate
);
response.Should().Be(expectedValue);
actualValiationString.Should().Be(expectedValidationString);
}
[Theory]
[MemberData(nameof(GetBoolTestDataWithDefaultValueAndAction))]
public void GetBoolWithDefaultValueAndActionShouldReturnBool(
Dictionary<string, string> metadata,
bool defaultValue,
bool expectedValue,
string expectedValidateString
)
{
var actualValiationString = string.Empty;
void messageBuilder(string validationString)
=> actualValiationString = validationString;
var validationDelegate = new Action<string>(messageBuilder);
var actualValue = DictionaryExtensions.GetBool
(
metadata,
MetadataKey,
defaultValue,
validationDelegate
);
actualValue.Should().Be(expectedValue);
actualValiationString.Should().Be(expectedValidateString);
}
-
2Show us your attempts at solving this.Flater– Flater2023年03月01日 03:47:03 +00:00Commented Mar 1, 2023 at 3:47
-
I don't think explicitly creating a delegate is needed; just pass the local function directly. Or write it as a lambda inline. Then the code overhead is lower.Sebastian Redl– Sebastian Redl2023年03月01日 10:33:35 +00:00Commented Mar 1, 2023 at 10:33
1 Answer 1
Bundle the delegate and the local variable in a class:
class Validator
{
public string ActualValidationString { get; private set; } = string.Empty;
public void Validation(string msg)
{
ActualValidationString = msg;
}
}
Now you can use it this way:
var validator = new Validator();
var actualValue = DictionaryExtensions.GetBool
(
metadata,
MetadataKey,
defaultValue,
validator.Validation
);
actualValue.Should().Be(expectedValue);
validator.ActualValidationString.Should().Be(expectedValidateString);
Using a class is probably the most idiomatic solution in C#. But if you really insist in a "single private method", one can also implement this in terms of two closures sharing a common variable:
static (Action<string>, Func<string>) CreateValidator()
{
string actualString=string.Empty;
return (s => actualString=s , () => { return actualString;});
}
This has to be used this way:
var validator = CreateValidator();
var actualValue = DictionaryExtensions.GetBool
(
metadata,
MetadataKey,
defaultValue,
validator.Item1
);
actualValue.Should().Be(expectedValue);
validator.Item2().Should().Be(expectedValidateString);
This solution is a little shorter than the first one, but may - argueably - a little bit harder to grasp if one isn't used to functional programming.