-
-
Notifications
You must be signed in to change notification settings - Fork 812
VerifyNoOtherCalls fails due to calls on another Mock instance #892
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
Comments
(Duplicate of #858.) Thanks for taking the time to report this.
That change was made intentionally, however I think we forgot to mention it in the changelog.
I understand, and that makes perfect sense. However, note that restoring this behavior would re-introduce an inconsistency in the verification APIs. Here's the line of thinking that led to the "bug" / behavior that you're seeing now:
Now I'm not saying that this is necessarily a sensible state of things, however given a choice between breaking the long-time behavior of I'm mentioning all this in such detail in the hope to get opinions about how verification would ideally work.
You can also fix this by changing |
P.S.: One alternate way of looking at this would be that mocks "own" setups instead of sub-mocks, and only the owned setups get included in verification. Setups might then "target" a mock that is different from the one "owning" it. (Which leads to a whole bunch of new questions such as, "When setup S owned by mock A sets up mock B, and you inspect B's setups, will you see S? Or do you only see S when inspecting A's setups?", or, "When you verify B, will S be included? Or only when you verify A?") This seems like a promising perspective, but I have no idea whether it would pass existing unit tests. |
Thank you for the comment, and I'm sorry for the duplication. I've tried the solution and it does work, thank you for that. If you don't mind me making a suggestion: So my suggestion is maybe to give VerifyNoOtherCalls an optional parameter stating the VerifyBehaviour in a similar sense as MockBehaviour. With options as 1) recursive (default), and 2) nonrecursive. In this manner the developer can make it explicit what it verifies, because "() => mock" seems not that explicit. At least if it is possible. And unintentionally it is possible to have both the earlier behavior and the intended behavior for VerifyNoOtherCalls. |
Well said, I agree. Thank you for the suggestion. I'll run a few tests over the weekend. Perhaps we can have our cake and eat it by fixing mock/setup ownership. An optional parameter (switch) should only be added as a last resort, I think. |
I have a working prototype for the proposal ("mocks own setups, not other mocks"). Unfortunately, during its development, I stumbled over the following unit test (among a few others of the same kind): which has been there for at least 6 years and specifies that when it comes to verification, mocks indeed "own" other mocks. Making the change that we've been discussing here would therefore be a breaking functional change, unfortunately. |
Recently for the company I work at, we upgraded the version of Moq from 4.8.3 to 4.12.0, due to reasons of other upgrades. However by doing this a number of our unit tests started to fail all of a sudden. After some investigation we found out that the unit tests fail due to VerifiyNoOtherCalls(). And it does not fail because there were other calls made to the checked mock, but calls made to another mock entirely.
I made a simplified version of the code in our product to see what the problem seems to be. The other mock that it fails on is connected to the mock that is verified, because the mock that is verified is setup to return that specific mock in a function call.
This is the simplified code I used to test this, and as an added note, we use NUnit for the testing framework.
Subject under test
My test classes
To me this seems like a bug. When I call VerifyNoOtherCalls on a specific mock I expect it to only check that one mock for no other calls. When it should check everything I personally expect something like Mock.VerifyNoOtherCalls.
For now we fixed this issue by either verifying the calls that it fails on of the other mock instance, or by verifying each individual function on the verified mock. However this invalidates my tests as soon as the code gets expanded.
The text was updated successfully, but these errors were encountered: