|
|
|
|
|
by sago
4083 days ago
|
|
> "Global variables" is really language specific terminology for global data. Strange, I thought it was terminology for global variables. > What I mean by "globals" in the scope of testing is "side-effects" Which is as whole different kettle of mackerel. Minimising side-effects is, of course, excellent advice, and can help with testing. But global variables and SL are not the same thing as side-effects. Your example (of testing a database) seems very confused to me. You're talking about coupling now. Not global variables. Why would you suddenly need a database connection? Why does the existence of global mutable state mean that nothing in your code can be tested independently? You seem to be imagining the worst case of coupling as an argument against service lookup. The last paragraph seems blatantly false. You're again straw manning this version of an SL that is mutated in arbitrary places through the code-base and therefore can't be tested in isolation, and neither can the components that use it. That is a strange version of SL you have here, and one that DI wouldn't help with. |
|
They're examples of side effects. It's not good enough to set the values of a global variable or register some service purely for the purpose of a test, because the test then does not reflect the runtime behavior of the code. The benefit of a unit test is to assert that code behaves the same way all the time - not just for specific values you use at the time of testing.
> Your example (of testing a database) seems very confused to me. You're talking about coupling now. Not global variables. Why would you suddenly need a database connection? Why does the existence of global mutable state mean that nothing in your code can be tested independently? You seem to have a strange idea of how software works.
Global variables increase coupling - code which consumes a global variable now has a dependency on all of the code which mutates it. You simply cannot test the consuming code in isolation without regard for the code mutating the variable, unless your test is exhaustive of every possible value which the global variable may contain.
My example was not of testing a database, it was about testing algorithms or logic that might exist inside some class named "Person", but which has a data dependency on an actual person (held in a database). If one wants to test the logic only, then mock data must be supplied instead of the real data from the database - else you're not testing only the person, but also testing that the database is connected and querying it is successful. The correct way to test this is to decouple Person from the database, usually be means of a mock object, or by passing the mock data into the person directly. Either way, it seems the blog author does not do such unit tests, as he doesn't use mock objects.
> I do not use mock objects when building my application, and I do not see the sense in using mock objects when testing. If I am going to deliver a real object to my customer then I want to test that real object and not a reasonable facsimile This is because it would be so easy to put code in the mock object that passes a particular test, but when the same conditions are encountered in the real object in the customer's application the results are something else entirely. You should be testing the code that you will be delivering to your customers, not the code which exists only in the test suite.
The problem with the author's philosophy is that it means when problems do arise in his applications, he must perform whole system testing/debugging to find them. He is missing perhaps the main benefit of unit tests - which is that, when a bug arises, you can quickly eliminate many possible causes because unit tests against those parts of code have succeeded (unless your unit tests were wrong to begin with, which will more or less be the case if they're testing against code which depends on globals).