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

NUnit2021 error shown when comparing Uri and string #561

Closed
IlIlIllIllI opened this issue Jul 7, 2023 · 2 comments · Fixed by #584
Closed

NUnit2021 error shown when comparing Uri and string #561

IlIlIllIllI opened this issue Jul 7, 2023 · 2 comments · Fixed by #584
Assignees

Comments

@IlIlIllIllI
Copy link

IlIlIllIllI commented Jul 7, 2023

If you try to Assert that a Uri is equal to a string, the NUnit Analyzer shows an NUnit2021 error:

The EqualTo constraint always fails as the actual and the expected value cannot be equal csharp(NUnit2021)

But Uri must have some overloaded Equals() logic that lets you compare Uri and string:

string testString = "test";
Uri testUri = new Uri("test", UriKind.Relative);

bool result = testUri.Equals(testString); // True

https://dotnetfiddle.net/seNXx9

I recently discovered this when I enabled the NUnit Analyzer in my test projects and discovered that the tests have always been passing when comparing two separate objects.

I know this is similar to #186

@manfred-brands
Copy link
Member

There is a special piece of code in Uri.Equals allowing comparison with string.

Maybe we need to add well known special cases to the analyzer in order not to complain about those.

@manfred-brands
Copy link
Member

This behaviour for Uri is inconsistent: testUri.Equals(testString) returns true but testString.Equals(testUri) not.
And testUri == testString doesn't even compile.

The following code shows problems with this:

[TestCase("test")]
public void TestUriWithString(string testString)
{
    var testUri = new Uri("test", UriKind.Relative);

    bool result = testUri.Equals(testString);
    Assert.That(result, Is.True);
    result = testString.Equals(testUri);
    Assert.That(result, Is.False);

    Assert.Multiple(() =>
    {
        Assert.AreEqual(testString, testUri, "AreEqual: string - Uri");
        Assert.AreEqual(testUri, testString, "AreEqual: Uri - string");

        Assert.That(testUri, Is.EqualTo(testString), "Uri, Is.EqualTo(string)");
        Assert.That(testString, Is.EqualTo(testUri), "string, Is.EqualTo(Uri)");
    });
}

This code actually fails half the tests:

  Message: 
Multiple failures or warnings in test:
  1)   AreEqual: string - Uri
  Expected: "test"
  But was:  <test>

  2)   Uri, Is.EqualTo(string)
  Expected: "test"
  But was:  <test>

For proper equality, the operation should be symmetric: a == b means b == a which is not the case for this overload.

Who am I to say that the Uri.Equals(string) interpretation shouldn't have been there.

I added code to recognize this in the analyzer.

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