--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
I'm not entirely sure that this would be a good idea (and I have mixed feelings about the example that Burcu showed too) because when tests fail (too often in code I'm not familiar with) I find myself tracing through to see what's going on, and this would make it quite unclear when something might be using a mock, and therefore which code might be responsible for the failure.
Personally I quite like the approach of explicitly defining the external things that need to be mocked as variables.
e.g.
// somepkgFoo is defined as a variable
// so that it can be overridden for
// testing purposes.
var somepkgFoo = somepkg.Foo
and overriding them in tests. (It would be nice if the compiler could tell in the production code that the variable is never assigned and treat it exactly as if it had been defined as a regular function but usually the performance impact is negligible.)
This makes it straightforward to change some specific behaviour for the duration of a test.
This doesn't get you everywhere though - it is harder when the external functions return concrete types. Sometimes I interpose a little mocking facade that defines everything in terms of interfaces, which can work ok.
If you *could* override a package for tests, there would be some interesting questions raised:
- would it override that package for every other package too?
- if not, would the types be compatible?
- what about external test harness code that happens to use the package that's being tested (this isn't that uncommon)? There are some grey areas here actually where you "kinda" have two versions of the package being tested in the system.
- how would you actually specify the overridden package?
- would the original package still be available to the tests?
FWIW I think this is an interesting discussion - we write a great deal of test code and how do to do it best is still an open question in my mind.
cheers,
rog.
I'm not entirely sure that this would be a good idea (and I have mixed feelings about the example that Burcu showed too) because when tests fail (too often in code I'm not familiar with) I find myself tracing through to see what's going on, and this would make it quite unclear when something might be using a mock, and therefore which code might be responsible for the failure.
I don't remember having seen this idea proposed before, yet it feels simple enough that somebody must have thought of it. So, here it goes:Could we allow the _test.go files to override a package that's imported by the non-test files? If this were possible, then we can do away with some unnecessary interfaces, and also avoid injecting dependencies just for the sake of testability.In Vitess, we have some non-elegant code that tries to mock out things like mysql, especially for creating specific failure scenarios. We do use the real thing as much as possible, but there are situations where it's not practical.
Could we allow the _test.go files to override a package that's imported by the non-test files? If this were possible, then we can do away with some unnecessary interfaces, and also avoid injecting dependencies just for the sake of testability.In Vitess, we have some non-elegant code that tries to mock out things like mysql, especially for creating specific failure scenarios. We do use the real thing as much as possible, but there are situations where it's not practical.Can you point out the exact code locations where these problems occur? It would make the discussion clearer.
Right now, anybody that needs to mock out a low level layer (or object) has to introduce an interface that was not needed till then, and figure out a way to replace the real thing with the mock. And this should preferably done with distorting the original code.
The main principles I'm trying to withhold are:1. Write the code in the most readable form, like it should work on production.2. Do not distort code for the sake of testing.3. Do not intermix testing code with non-testing code.Unfortunately, with the way the language and tooling is currently defined, it's pretty much not possible to achieve all the above three objectives.