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

Method setup broken when specifying the same parameters in a different order in setup #252

Closed
adamreeve opened this issue Mar 15, 2016 · 3 comments · Fixed by #262
Closed

Comments

@adamreeve
Copy link

Code to reproduce:

using Moq;
using Xunit;

public class MoqTest
{
    [Fact]
    public void MoqWorks()
    {
        var a = new MyClass();
        var b = new MyClass();
        var mock = new Mock<IDoStuff<MyClass>>();
        mock.Setup(m => m.DoStuff(a, b)).Returns(1);
        mock.Setup(m => m.DoStuff(b, a)).Returns(1);
        Assert.Equal(1, mock.Object.DoStuff(a, b));
        Assert.Equal(1, mock.Object.DoStuff(b, a));
    }

    public interface IDoStuff<in T>
    {
        int DoStuff(T a, T b);
    }

    public class MyClass { }
}

Both asserts should pass but one fails as DoStuff returns the default value of 0.

This was tested with Moq version 4.2.1510.2205.

@adamreeve
Copy link
Author

This isn't dependent on having a generic interface, this simplified test case also shows the same issue:

using Moq;
using Xunit;

public class MoqTest
{
    [Fact]
    public void MoqWorks()
    {
        var a = new MyClass();
        var b = new MyClass();
        var mock = new Mock<IDoStuff>();
        mock.Setup(m => m.DoStuff(a, b)).Returns(1);
        mock.Setup(m => m.DoStuff(b, a)).Returns(1);
        Assert.Equal(1, mock.Object.DoStuff(a, b));
        Assert.Equal(1, mock.Object.DoStuff(b, a));
    }

    public interface IDoStuff
    {
        int DoStuff(MyClass a, MyClass b);
    }

    public class MyClass { }
}

It does seem related to the type of the arguments though, using ints doesn't show this problem, this test passes:

using Moq;
using Xunit;

public class MoqTest
{
    [Fact]
    public void MoqWorks()
    {
        const int a = 99;
        const int b = 123;
        var mock = new Mock<IDoStuff>();
        mock.Setup(m => m.DoStuff(a, b)).Returns(1);
        mock.Setup(m => m.DoStuff(b, a)).Returns(1);
        Assert.Equal(1, mock.Object.DoStuff(a, b));
        Assert.Equal(1, mock.Object.DoStuff(b, a));
    }

    public interface IDoStuff
    {
        int DoStuff(int a, int b);
    }
}

Strings also work, so it's not a reference type vs value type issue, but could be related to those types implementing IEquatable?

@LeonidLevin
Copy link

This has to do with how hash code is calculated for ExpressionKey objects.
I am working on it now.

LeonidLevin pushed a commit to LeonidLevin/moq4 that referenced this issue May 21, 2016
@kzu kzu closed this as completed in #262 May 22, 2016
kzu added a commit that referenced this issue May 22, 2016
Fixed setup issues when specifying the same parameters in a different order (issue #252)
@adamreeve
Copy link
Author

Great, thanks for fixing this @LeonidLevin!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants