-
-
Notifications
You must be signed in to change notification settings - Fork 802
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
Regression in 4.13.0 #932
Comments
@stakx This call sequence throws:This does not, however:Type definition:However, I still haven't found a simple repro (creating a moq of a list of the interface before the type doesn't trigger the problem). |
Thanks @BrunoJuchli for reporting. I'm not sure why you're saying that you haven't found a repro yet. Based on the information you've posted, I've hacked together the following, which produces the exception you've described: [Fact]
public void Test()
{
var mock = new Mock<X> { DefaultValue = DefaultValue.Mock };
mock.Object.Method<I>();
mock.Object.Method<C>();
}
public interface X
{
IReadOnlyList<T> Method<T>();
}
public interface I { }
public class C : I { }
That repro is good enough for me to start digging. Of course, as always, you're more than welcome to help digging, too! |
While debugging the above repro, I noticed that the TL;DR: This is a bug, and I can probably draft a fix during the next week or so. Read on if you're interested in the technical background. When your mock uses The
What seems to have gone wrong in 4.13.0 is that the caching logic (1) wasn't updated to reflect the changes in (2). The "cache" entry is created here: When I say "caching", what really happens behind the scenes is that Moq creates an internal setup for Due to change (2) mentioned above, a call to I might be able to draft a bugfix during the next week or so. What I'm thinking of right now is that these kinds of internal "cached return value" setups should somehow be made to disregard type variance when matching calls against the set up method, and only match the precise generic arguments as were used when the cache entry was created. |
@stakx |
@stakx |
@BrunoJuchli, great to hear! Thanks for letting me know. |
After updating from 4.12.0 one of our tests fails, consistently every time I run it.
I've got a really hard time reproducing it, though, because call sequence, type definitions, inheritance and maybe even thread switches may play a role.
Before reading through all the complicated blabla below jump right to this comment
I've got a class:
A test which sets up the mock like:
No further setups.
Tthe test performs quite a lot of steps (it's not a class-level unit test), and at one point it fails here:
Inspecting the moq invocations I can see the reason:
Moq has actually created a mock of
IReadOnlyList<IHaveCellComponet>
instead ofIReadOnlyList<StorageViewModel>
:Trying to Reproduce
Calling
.Retrieve<StorageViewModel>
immediately after the creation of the moq succeeds.Also, the exception that originally occurred now doesn't happen anymore. All further calls to
.Retrieve<StorageViewModel>
succeed.The test still fails, further down, when retrieving an IReadOnlyList of another type,
MachineBaseViewModel
:"further down" is proven by there being more invocations than the first time:
When I add another
.Retrieve<MachineBaseViewModel>()
right after creation of the moq, we get even further.This means, in the time between creation of the Moq and calling
Resolve
something is happening which get's Moq to behave erratic. But I don't have a clue to what that is. I can't find any other access toMock<ViewModelCache>
, only toMock<ViewModelCache>.Object
.Within our solution this reproduces reliably, but I haven't found the key to creating a repro yet.
The text was updated successfully, but these errors were encountered: