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

The result of setting up methods in an hierarchy of interfaces depends on the order by which they're set up #131

Closed
dcastro opened this issue Sep 7, 2014 · 5 comments

Comments

@dcastro
Copy link

dcastro commented Sep 7, 2014

Test Types:

public interface BaseA
{
    string Method();
}

public interface BaseB
{
    string Method();
}

public interface Derived : BaseA, BaseB
{
    new string Method();
}

Reproduce bug:

var mock = new Mock<Derived>();

mock.Setup(x => x.Method())
    .Returns("a");
mock.As<BaseA>().Setup(x => x.Method())
    .Returns("b");
mock.As<BaseB>().Setup(x => x.Method())
    .Returns("c");

var derived = mock.Object;
Assert.Equal("a", derived.Method());            //equals "c" <---- Test fails
Assert.Equal("b", (derived as BaseA).Method()); //equals "b"
Assert.Equal("c", (derived as BaseB).Method()); //equals "c"

If I change the order of the setups, so that Derived.Method is configured last, the program now prints "a", "b", "c" as expected and the tests pass.

var mock = new Mock<Derived>();

mock.As<BaseA>().Setup(x => x.Method())
    .Returns("b");
mock.As<BaseB>().Setup(x => x.Method())
    .Returns("c");
mock.Setup(x => x.Method())
    .Returns("a");

var derived = mock.Object;
Assert.Equal("a", derived.Method());            //equals "a"
Assert.Equal("b", (derived as BaseA).Method()); //equals "b"
Assert.Equal("c", (derived as BaseB).Method()); //equals "c"
@pjquirk
Copy link

pjquirk commented Jan 22, 2015

I found this bug independently today working on an answer for this question on StackOverflow. Hopefully what I found can help.

@stakx
Copy link
Contributor

stakx commented Jun 28, 2017

Related: #22, which is also about shadowed members. It appears that it's not entirely clear what Moq does / should do in such cases.

@stakx
Copy link
Contributor

stakx commented Jul 11, 2017

@pjquirk, well spotted, this line of code, like you mentioned in your answer on Stack Overflow, indeed seems to be the reason for this peculiar behavior. Thanks for helping to identify the problem's cause!

I'll look into this some more tomorrow. My current guess is that it should be possible to first attempt to find a precise match, and only if there is none (or several equally good matches), fall back to the current .LastOrDefault behavior.

@stakx
Copy link
Contributor

stakx commented Jul 12, 2017

This should be fixed in the next release of Moq (version >4.7.63).

@stakx stakx closed this as completed Jul 12, 2017
@pjquirk
Copy link

pjquirk commented Jul 12, 2017

Thanks for the fix @stakx, and glad I could be of some use!

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

No branches or pull requests

3 participants