4 ms·
While I see your point, if you ever find yourself wishing for monkey patching while writing a test in a statically typed language, it's a code smell. You've not
by nrinaudo 11y ago
While I see your point, if you ever find yourself wishing for monkey patching while writing a test in a statically typed language, it's a code smell. You've not abstracted things enough. If you need to modify things that way but can't, you should consider abstracting over it and making it possible at runtime.
That way, not only do you get to write a better test - a whole class of errors is gone, just not possible anymore - you also have a more modular system, the components of which you can test individually.
- phamilton 11y agoDHH captures this very well http://david.heinemeierhansson.com/2012/dependency-injection-is-not-a-virtue.html http://david.heinemeierhansson.com/2012/dependency-injection... I think his example of system time is a good one because an abstraction in that case often only serves to enable testing. If testing is already possible, then that abstraction is just unneeded complexity
- nrinaudo 11y agoWithout any sarcasm of any kind, I expect I must be missing the point of what you linked and would love for you to clarify it. What I understood was, changing the way time is handled for your entire Ruby process in order to test that some publish function sets the right date is good practice. As opposed to, say, have it expect a date argument, which lets you test it without side effects that can impact absolutely everything else, and gets you a more powerful feature, publishAt rather than just publishNow. If I understood this correctly (which I honestly doubt), I don't think our conversation serves much purpose. You seem to regard as good practice what I consider utter lunacy. I don't pretend that I'm right, just that there's absolutely no chance that we'll agree on this. That being said, your point about introducing abstraction for the sole purpose of enabling tests is well made. My experience is that you'll often end up glad you abstracted over whatever it was you needed for the tests and use it in live code, but not 100% of the time. But if the alternative is global mutable states, I'll consider un-needed abstraction the lesser of two evils and gladly embrace it.
- phamilton 11y agoI'm surprised at the shock and awe. It's a test. It's not production code. It runs and is able to verify behavior. It runs isolated, and no other code is running when it does. Building publishAt is more powerful than publishNow, but building something more powerful than what you need is hardly good practice. And you still end up with the problem of how you test the code calling publishAt. This isn't some whack job in the corner saying something he came up with is a good idea. This is how the Ruby community thinks and writes software, with great success. And it does in fact clash with other communities. The point of this discussion isn't really whether one approach is better than the other. The point is that our tools (specifically dynamic languages with flexible metaprogramming) drastically influence our view of what is acceptable. Your strong disagreement demonstrates the point.
- dllthomas 11y ago> I don't think our conversation serves much purpose. You seem to regard as good practice what I consider utter lunacy. It seems to me that, if you're able to unpack that all and get at why these dramatically contradictory beliefs are held, someone is likely to learn a lot (perhaps both parties!). That sounds like good purpose to me.