Miško, I like how you highlighted problems with the design that go beyond testing. I think a lot of the bad practices you point out are problematic in this way. I'd like to see more posts of this nature as you might reach a wider audience (those that aren't yet test infected).
Why not just have the developers change "new CreditCard" or the c.charge() method call the init methods themselvs as needed?
Sure, these are co-dependant APIs. Your suggestion is to expose all that codependance to the world. I'd suggest keep your personal relationships to your self and let me use the APIs in a logical way.
That's not just good for testing its the mark of a good API.
My minor in college was Journalism. i learned really quickly how much information I could accumulate just by listening. If I wanted to to know something about someone or something, all I had to to was say something about the subject and the person(s) would open up and talk about it. It is so easy to find out information about people that it is mind boggling. I will say no more because there are people reading this that will take advantage of it.
My minor in college was Journalism. i learned really quickly how much information I could accumulate just by listening. If I wanted to to know something about someone or something, all I had to do was say something about the subject and the person(s) would open up and talk about it. It is so easy to find out information about people that it is mind boggling. I will say no more because there are people reading this that will take advantage of it.
The pathological liars in the singleton crowd also appear to have identity crises.
"The singleton pattern is implemented by creating a class with a method that creates a new instance of the class if one does not exist." - Wikipedia:Singleton pattern
If these were full-blooded singletons, then the accessors should be initialising the singleton if required. This makes using the singleton as simple as the initial "What happens if I execute this method" test.
This does put the tester's credit card in a bit of a pickle though. Perhaps the classes should expose an alternative initializer for mocking out?
That said, I wholly agree that being explicit about what a class will consume is much better than grabbing it out of some global sub-ether. As a bonus, it gives test 'seams' to tear apart.
testCreditCardCharge() { Database db = Database.getInstance(); OfflineQueue q = OfflineQueue.getInstance(db); CreditCardProcessor ccp = CreditCardProcessor.getInstance(q); CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(ccp, 100); }
I think this article is taking singleton discussion into wrong direction, idea of Singleton is to avoid instantiating multiple objects and flooding JVM. Author conveniently ignores actual cause.
You can keep Singletons and solve the problem of dependencies that this article discusses using my approach above.
Hehe, and another important lesson learned is test with 1 dollar values first.
ReplyDeleteGreat read b.t.w.
-Mark
Miško,
ReplyDeleteI like how you highlighted problems with the design that go beyond testing. I think a lot of the bad practices you point out are problematic in this way. I'd like to see more posts of this nature as you might reach a wider audience (those that aren't yet test infected).
-Mark
Why not just have the developers change "new CreditCard" or the c.charge() method call the init methods themselvs as needed?
ReplyDeleteSure, these are co-dependant APIs. Your suggestion is to expose all that codependance to the world. I'd suggest keep your personal relationships to your self and let me use the APIs in a logical way.
That's not just good for testing its the mark of a good API.
My minor in college was Journalism. i learned really quickly how much information I could accumulate just by listening. If I wanted to to know something about someone or something, all I had to to was say something about the subject and the person(s) would open up and talk about it. It is so easy to find out information about people that it is mind boggling. I will say no more because there are people reading this that will take advantage of it.
ReplyDeleteMick
My minor in college was Journalism. i learned really quickly how much information I could accumulate just by listening. If I wanted to to know something about someone or something, all I had to do was say something about the subject and the person(s) would open up and talk about it. It is so easy to find out information about people that it is mind boggling. I will say no more because there are people reading this that will take advantage of it.
ReplyDeletetwetyboyd
This comment has been removed by the author.
ReplyDeleteThe pathological liars in the singleton crowd also appear to have identity crises.
ReplyDelete"The singleton pattern is implemented by creating a class with a method that creates a new instance of the class if one does not exist." - Wikipedia:Singleton pattern
If these were full-blooded singletons, then the accessors should be initialising the singleton if required. This makes using the singleton as simple as the initial "What happens if I execute this method" test.
This does put the tester's credit card in a bit of a pickle though. Perhaps the classes should expose an alternative initializer for mocking out?
That said, I wholly agree that being explicit about what a class will consume is much better than grabbing it out of some global sub-ether. As a bonus, it gives test 'seams' to tear apart.
Why not do this?
ReplyDeletetestCreditCardCharge() {
Database db = Database.getInstance();
OfflineQueue q = OfflineQueue.getInstance(db);
CreditCardProcessor ccp = CreditCardProcessor.getInstance(q);
CreditCard c = new CreditCard(
"1234 5678 9012 3456", 5, 2008);
c.charge(ccp, 100);
}
I think this article is taking singleton discussion into wrong direction, idea of Singleton is to avoid instantiating multiple objects and flooding JVM. Author conveniently ignores actual cause.
You can keep Singletons and solve the problem of dependencies that this article discusses using my approach above.
2nd this comment
Delete