OK, so we now know that it's really easy to hook functions in the vbe7.dll with the EasyHook library. For those who missed it in chat, we would basically be intercepting VBA function calls and allowing user configurable output for unit tests - i.e. forcing MsgBox to return 42:

This opens the door to bypassing "disruptive" functionality like file access, user interaction, etc. during unit testing. But it also raises the question of how we want to extend that functionality to users. The main thing that we have to make absolutely sure that we do is get the hooks removed after the end of every test. My first thought for VBA syntax was something simple like:
Rubberduck.Fakes.MsgBox.Returns(vbOK)
That would be perfect if we could have a predeclared managed object, but I'm not sure that's possible. The alternative would be requiring another instance in the test...
Private Fakes As New Rubberduck.FakesProvider
...and call it like:
Fakes.MsgBox.Returns(vbOK)
The only problem there is that we'd be creating and returning some sort of object in order to allow chaining the call, which goes back to object tracking and disposal after the completion of each test.
A third option might be to configure everything internally:
Fakes("MsgBox", vbOK)
We also have to keep in mind that we can't rely on the user to not simply delete the VBA error handling code (this is probably also an issue with the AssertClass).
Finally, I'm not attached to the names FakesProvider or Fakes, so if there are other suggestions by all means throw them out there. Just remember that once it goes release we're probably stuck with it.
So, looking for thoughts and ideas before I start coding this sucker.
Linking #1550
I like the Private Fakes As New Rubberduck.FakesProvider approach - it's in line with the spirit of the current API. Although... I like how Private Ducks As New Rubberduck.DuckProvider is similar to Private Mocks As New Rubberduck.MockProvider 馃檮
Each member of FakeProvider could be a factory method that returns an object that's responsible for setting up & tearing down its own hooks... could we use the destructor for this or that would be too late?
A FakeProvider factory would pretty much have to be a singleton, so we could just inject a reference into the TestEngine and give it a method like StopFaking that would dispose all of the objects that it's produced. The TestEngine could just call that after each test was done. If the VBE tried to use the object after that, it would just be a VBA runtime error along the lines of "The COM server has disconnected from its clients".
There would be the potential that some smartass like me or @ThunderFrame would try to grab a reference to the returned object or use it outside of a test though. If we're handing object references out the FakeProvider would need to know whether or not unit tests were running anyway, so maybe have it return null if it isn't running a test?
You got me at StopFaking
So, wrapping every single callable VBA function/method is going to be quite an undertaking - should this be broken down into smaller issues and tracked in its own project?
It might be easier to track if we just opened one issue with a tasklist - i.e.:
Then, just edit the original issue comment if we run across one that needs to be added. I'm not sure we want hundreds of feature request issues for these.
You mean like these steps @comintern? https://help.github.com/articles/creating-an-issue-template-for-your-repository/ Just be advise to consider once these changes are applied they are likely global across all issues not to resolve fakemocking issues alone.
@PeterMTaylor - I was thinking of just a simple checklist, like a list of TODO items - more like an "open ended" feature request as opposed to a hundred or so separate issues. The templates are an interesting idea - it would be nicer if they could be tied to tags though.
No problems there, agreed 馃憤 Regarding todo list vs templates @comintern.
Would @retailcoder append/update his feature request with Github team if proven useful to RD as he mentioned tags with projects.
Closed via #2906 et.al.
Most helpful comment
A
FakeProviderfactory would pretty much have to be a singleton, so we could just inject a reference into theTestEngineand give it a method likeStopFakingthat would dispose all of the objects that it's produced. TheTestEnginecould just call that after each test was done. If the VBE tried to use the object after that, it would just be a VBA runtime error along the lines of "The COM server has disconnected from its clients".There would be the potential that some smartass like me or @ThunderFrame would try to grab a reference to the returned object or use it outside of a test though. If we're handing object references out the
FakeProviderwould need to know whether or not unit tests were running anyway, so maybe have it returnnullif it isn't running a test?