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

Setup of method with an IEquatable argument gets lost with newest moq version #319

Closed
Mys73rion opened this issue Jan 12, 2017 · 3 comments

Comments

@Mys73rion
Copy link

When we update to the moq version 4.5.30 the test below fails.

If we remove the "Equals" attribute (it is from Fody) from the class "Bar" the test succeeds.
With the previous version we don't have this problem.

The setup from "bar1" gets lost somehow.

[Fact]
public void FactMethodName()
{
    var bar1 = new Bar();
    var bar2 = new Bar();
    var foo = new Mock<IFoo>();
    foo.Setup(x => x.Foo(bar1)).Returns("aa");
    foo.Setup(x => x.Foo(bar2)).Returns("bb");
    foo.Object.Foo(bar1).Should().Be("aa"); // fails 
    foo.Object.Foo(bar2).Should().Be("bb");
}
public interface IFoo
{
    string Foo(Bar bar);
}
[Equals]
public class Bar
{
    public override string ToString()
    {
        return "Bar";
    }
}
@MartinBuehlmann
Copy link

Same issue here. Any plans..?

@kzu
Copy link
Contributor

kzu commented Feb 21, 2017

Moq now supports mocking Equals, GetHashCode and ToString, which likely has an unexpected interaction with Fody. Dunno how it's implemented though, and what we should be doing.

Marking as up-for-grabs for now.

Thanks for reporting it!

@stakx
Copy link
Contributor

stakx commented Jun 18, 2017

As far as I understand it, Moq's current behaviour (which breaks the reported use case) is actually correct and should not be changed.

[Equals]
public class Bar
{
    public override string ToString()
    {
        return "Bar";
    }
}

This type definition and Fody's processing of it means that although Bar is a reference type, comparing any two instances for equality will yield true. For instance:

var bar1 = new Bar();
var bar2 = new Bar();

bar1.Equals(bar2) == true. Therefore, the following two setups are equivalent (since Moq matches these arguments using object.Equals) and the last one overrides the first one:

foo.Setup(x => x.Foo(bar1)).Returns("aa");
foo.Setup(x => x.Foo(bar2)).Returns("bb");

I don't think we can, nor should, change this behaviour. Doing so would probably break far more existing Moq setups and tests than it would fix.

@stakx stakx closed this as completed Jun 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants