-
-
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
Provide non-generic API to support runtime type mocking #887
Comments
I think exposing an "SDK layer" in Moq v4 would be fantastic and worthwhile, but I should probably add a few words to justify the effort required to do, especially when Moq v5 is waiting just around the corner: We should only consider exposing the "plumbing" / SDK layer of Moq v4 if it is reasonably well-architected and well-designed. I've been doing refactoring work for the past two years or so in that general direction, however we're not quite there yet. But being able to make that layer of Moq v4 public, in my eyes, would be a sign of good code quality. So while I definitely want to do this, some work remains to be done, and it's not priority compared to e.g. bug fixes. So if that work ends up being mine, to give you a rough timeframe, don't expect to see results before approx. mid-2020. More specifically, what remains to be done?
|
Just giving a "Me too" to supporting exposing some internals (especially for creating setups) for use in 3rd party libs. I feel like it's a fairly niche case, of course, but wanted to add my hat to the pile. |
@dammejed: Cheers for the feedback. Can you give a brief summary of the Moq internals you're accessing through reflection? Just to get a better idea what you'd want to become public in some way or another. |
@stakx Sure. The DSL and its useage are proprietary, so I can't share the code, but the general idea is this: There are some generated expressions which are too complicated for Moq's expression visitor to understand and extract expressions from, so that it can match the called method and generate expression argument matchers. The DSL I maintain is able to extract the method and argument expressions, then simplify them to something understandable by Moq. It then directly creates the The rest of the code is able to rely on the existing |
Just to provide some data point. Currently, I'm using those methods:
There are a number of items such as |
@bclothier @dammejed I've finally made some progress towards an untyped API; see #1002. After some internal refactoring, this sort of grew quite easily on top of existing code. It may not be precisely what you need but perhaps it would take you closer to where you want to be? Any feedback is appreciated. |
Thanks for doing this, @stakx! I took a very brief look, and it looks promising for my usecase! One suggestion that could potentially make it easier for me to migrate-- I don't necessarily need those to exist, but with my current infrastructure, the behaviors and the invocation shape are supplied at different times (e.g., with a fluent-style setup, as in the base moq library). One way I could emulate that with the behavior-based extensions would be to allow adding more behaviors after the fact, e.g., mock.Setup(lambdaExpr, new Behavior[] { new CoolBehavior()})
.WithBehavior(new EvenCoolerBehavior()); In the current implementation, a behavior-based setup is immutable once added. Supporting mutating the behaviors after the fact might ease the transition for me. Not sure if that's counter to your design goals. Let me know. Then again, I could always write a behavior that fully encompasses any customizations I would otherwise make after the fact and mutate it myself, I suppose. I'll make a deeper investigation this week and come back. Thanks again! |
@dammejed that's definitely something that should be possible! While this could be done now for mock.Setup(...);
var setup = mock.Setups.Last();
setup.Behaviors.Add(...); On the other hand, if we enabled this now just for the new setup type, we'd probably have to expose a |
Nice. Makes sense to me! |
Normally, Moq uses generic APIs which is a great thing for ensure strong-typed, refactor-friendly mocking API. However, when the scenario is that we need to mock a runtime type, we can descend into a hell of
Expression
s trying to use the generic API.The proposal is to open the non-generic methods as an API on an interface that is not easily accessible. In @stakx 's words:
The scenario for wanting to mock a runtime type is to provide support to other languages outside C#. In my case, it's VBA language and we have a prototype here which is for VBA language. The users would be able to write some mocks for the unit tests in VBA which would use Moq underneath.
While we could have made our own mocking framework, that would considerably enlarge our project's scope and we'd rather not have to get into whole journey of learning how to write a good mocking framework but rather ride the coattails of the developers who already invested so much into building an excellent mocking so that we can only focus on providing an effective implementation in our project.
The text was updated successfully, but these errors were encountered: