-
-
Notifications
You must be signed in to change notification settings - Fork 794
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
Allow hidden methods to be mocked #22
Comments
Interesting, this works. What do I miss? public interface IMyCollection : IEnumerable<int>
{
}
[Test]
public void TEST()
{
//arrange
var list = new List<int> {1, 2, 3};
var mock = new Mock<IMyCollection>(MockBehavior.Strict);
mock.Setup(m => m.GetEnumerator()).Returns(list.GetEnumerator());
//act
var first = mock.Object.First();
//assert
first.Should().Be(1);
} |
Also, there is already a mechanism to get another interface and set it: var mock = new Mock<IMyCollection>(MockBehavior.Strict);
var ienum = mock.As<IEnumerable>();
ienum.Setup(e => e.GetEnumerator()).Returns(list.GetEnumerator()); |
Real world example of when some syntactic sugar would be nice.
This is a situation where to properly set up the mock, we need to repeat ourselves and provide the same implementation twice. |
@tkellogg, @rubberduck203: Do you still wish to follow up on this, or can we close this? I guess the original question has been answered? @rubberduck203: When you implement In my opinion, the problem here does not lie with Moq missing something, but with the .NET Framework having something too much. |
@stakx I don't know how now works under the hood. If you believe it would be a burden to create & maintain then I would close this. It's not a terrible burden to setup both methods once you understand it. When I originally faced this issue I spent 6 hours in a state of utter confusion though. I believe this could be solved with an update to the documentation. |
Fair enough. So basically, what you are saying is that I am not against an improvement, I was just under the false impression that this issue was specifically about If you have any suggestions what kind of new syntax could help this, let's discuss it. ;) |
IEnumerable & IEnumerable were just my specific use case (although, likely the most likely one). I could see a default behavior (as a user) of setting up both the visible & hidden method on a single call, but understand if it's not reasonable to implement. I'll add something to the QuickStart. You can close this as far as I'm concerned. |
I have some trouble understanding what exactly is being asked here. The original code example probably isn't ideal because, like @sloncho already pointed out, the shown code actually works. @tkellogg: I'll try to rephrase your issue in more general terms. Is this what you meant? public interface IA
{
int GetValue();
}
public interface IB : IA
{
new int GetValue();
}
[Fact]
public static void ShadowedMembersAreSetUpLikeShadowingMember()
{
const int expected = 42;
var mock = new Mock<IB>();
mock.Setup(_ => _.GetValue()).Returns(expected);
var b = (IB)mock.Object;
Assert.Equal(expected, actual: b.GetValue()); // => passes
var a = (IA)mock.Object;
Assert.Equal(expected, actual: a.GetValue()); // => fails!
} And, if this is the problem we're talking about, are you asking that shadowed members (like |
The primary example of this is mocking IEnumerable:
The
IEnumerable<Item>.GetEnumerator()
actually hidesIEnumerator.GetEnumerator()
. As a result, this setup code only sets up the generic versionWhen you use Linq methods, like
mock.Object.FirstOrDefault()
, it tries to use theIEnumerable.GetEnumerator()
method. We need a way to conveniently do this setup.I propose that we also setup all hidden methods/properties by default. So if you do that
mock.Setup(x => x.GetEnumerator())
, it just works.I also propose that we support a cast in the Setup expression,
mock.Setup(x => ((IEnumerable)x).GetEnumerator())
to be specific about which method we're talking about.The text was updated successfully, but these errors were encountered: