question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

The testing method WithCustomState doesn't work properly when the state is a string resulting from a concatenation.

See original GitHub issue

How to reproduce: Add a validation that has a custom state as follow: .WithState(x => "Test" + "123");

Add a unit test for this validation and try to assert it as follow: .WithCustomState("Test123");

The test will fail with the message:

Message: 
        FluentValidation.TestHelper.ValidationTestException : Expected custom state of 'Test123'. Actual state was 'Test123'

I have got the same error using no matter what form of concatenation: StrigBuilder, String.Format, $ operator, + operator.

If you remove the concatenation from the validator and use it just as follow, the test works fine: .WithState(x => "Test123");

The nuget version I used is the latest at this moment: 9.5.1.

Could someone check that please? Thanks.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
JeremySkinnercommented, Mar 1, 2021

I see what’s happening. Internally a reference equality check is being performed. This example illustrates the problem:

object s1 = "Test" + 123.ToString();
object s2 = "Test123";

bool check1 = s1 == s2; // False
bool check2 = s2.Equals(s1); // True

Becuase the == operator is used against variables of type object, the wrong type equality check is performed. Internally this is what FluentValidation is doing.

When explicitly typed as strings, the result is as expected:

string s1 = "Test" + 123.ToString();
string s2 = "Test123";

bool check1 = s1 == s2; // True

Internally FluentValidation needs to be changed to use .Equals, and also should optionally accept an IEqualityComparer. To work around this for now, you can add your own test extension that takes a comparer:

public static class MyExtensions {
  public static IEnumerable<ValidationFailure> WithCustomState(this IEnumerable<ValidationFailure> failures, object expectedCustomState, IEqualityComparer comparer) {
	  return failures.When(failure => comparer.Equals(failure.CustomState, expectedCustomState), $"Expected custom state of '{expectedCustomState}'. Actual state was '{{State}}'");
  }
}

…which you can then use like this:

result.ShouldHaveValidationErrorFor(x => x.Surname).WithCustomState("Test123", StringComparer.Ordinal);

I’ll also ensure this is updated for a future version and I’ll post here once it’s done.

0reactions
JeremySkinnercommented, Mar 8, 2021

Implemented in 9.5.2

Read more comments on GitHub >

github_iconTop Results From Across the Web

The testing method WithCustomState doesn't work properly ...
The testing method WithCustomState doesn't work properly when the state is a string resulting from a concatenation. #1658.
Read more >
How to fix my string concatenation that isn't working?
1 Answer 1 ... Syntax for string concatenation is incorrect. You are contacting string with object. {longitude} means {longitude : longitude}.
Read more >
Custom State — FluentValidation documentation
The WithState method allows you to associate any custom data with the validation results. We could assign a custom state by modifying a...
Read more >
Release Notes and History
Fixed Process activity not resetting the object's state when the object is preempted. ... Fixed Slot Label Painter not recognizing strings properly.
Read more >
String Concatenation issue
Hi, We need to concatenate validation strings i.e. validation error messages from different parts of the rule/conditions and we are facing ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found