• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Bear Bibeault
  • Junilu Lacar
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • salvin francis
  • Frits Walraven
Bartenders:
  • Scott Selikoff
  • Piet Souris
  • Carey Brown

implement vending application

 
Bartender
Posts: 3323
86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Very informative and interesting Junilu, well done and have a cow.
 
Ranch Hand
Posts: 228
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A great thread to read. Thank you Junilu for spending time to share the knowledge of TDD.
I followed the thread from the starting and have coded for VendingMachine and CustomerPanel.
I will post some of my code here, For some feedback from Junilu or anyone else.



I understand that there is no documentation done on any of the method.

Great topic by s ravi chandran.
 
Marshal
Posts: 15877
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry I haven't been able to respond sooner but I'm a bit swamped at work, having been away on vacation for a few weeks. I appreciate the kind comments from everyone who has put in the time to follow this discussion and will get back to you with some feedback as soon as I get caught up with work in my day job.
Regards to all and I hope you have had a great start to the New Year. From Columbus OH, home of The Ohio State Buckeyes, champions of the first ever College Football Playoff, GO BUCKS!!!
 
Junilu Lacar
Marshal
Posts: 15877
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Some feedback:

First of all, I think you are continuing to show progress. Good job.

initial_amount_should_be_zero() - The name is good: it's to the point and says exactly what the intent of the test is. The test code can still be improved and the way you've written it should have evoked these questions:

1. Why would I have to add a 0 value coin to get the initial amount? Should I have another way of determining how much money has been deposited so far instead? Is this code telling me that I need to add a getter method for amountDeposited?

2. How should this method behave when an invalid coin value is entered? Should I even account for this possibility right now?

When I write a test, I read it back out loud. If I'm working in a group or pair, someone will read it out loud for the others. This helps us "listen" to what the code is saying and see if it makes sense. But here's the trick: sometimes it's better not to read the code verbatim but "translate" it a bit. Here's how I would do that for this test as you have written it:

I have a zero-value coin and I have a new CustomerPanel. I deposit my zero-value coin and I get back the total amount deposited so far, which should be zero.


When you read this out loud, it sounds a little silly and should make you ask the questions above.

Compare that with this:

I have a new CustomerPanel and I haven't deposited any money yet. The CustomerPanel should tell me that the total amount deposited so far is zero.


This sounds more sensible and here's what the test code for it would look like:

Line 3, the line that declares local variable newPanel, might represent some duplication with code in the @Before setup method but in this case, I can live with it because I think it makes this particular test code more cohesive by having a local instance of CustomerPanel. We could have also just used the instance that was created in the setup method but that would require a reader to bounce around the code a little. Either approach is fine but I personally prefer the local variable in this case because there's no other code that sets up the context for the test.

Note also that in the second "translation" I say "and I haven't deposited any money yet". There is no actual test code that corresponds to this so it's really an interpretation on my part as I read the code and see that there is no statement where money is actually deposited. That is, the lack of code also means something in this context and the local variable newPanel helps set that context up and make it easier to discern.

Of course, since we're doing TDD, this new version of the test code should fail compilation at first since there should not be a getAmount method yet. Once that's fixed, the test will pass and go Green. That should give you a slight pause because you haven't seen the test fail yet. I would probably just temporarily change the assertion to assertThat(newPanel.getAmount(), is(1)) to see it fail, then put it back to is(0) to get the Green bar back. Another approach would be to intentionally introduce a bug in the CustomerPanel class, perhaps initializing the amount field to a non-zero value in the constructor, just to see the test fail. Then get the Green bar back by removing the intentional bug. Either way, making sure that the test fails first provides you with a sanity check that tells you the test is actually useful for demonstrating some aspect of the behavior of the code under test.
 
Junilu Lacar
Marshal
Posts: 15877
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:
Note also that in the second "translation" I say "and I haven't deposited any money yet". There is no actual test code that corresponds to this so it's really an interpretation on my part as I read the code and see that there is no statement where money is actually deposited. That is, the lack of code also means something in this context and the local variable newPanel helps set that context up and make it easier to discern.


It's kind of difficult to predict whether or not it would actually happen in a live conversation between developers but I could also imagine that if I or someone on my team had said the above, someone could have also offered an alternative: Why not document that in the test name then instead of leaving it up to interpretation, and possibly missing it, by the reader? That is, why don't we refactor the test name to getAmount_should_be_zero_when_new_instance_and_no_coins_deposited or something like that. I would readily agree and accept this refactoring suggestion and would even be amenable to using the instance of CustomerPanel created in the setup method instead of a local variable

or

Actually, now that I look at both versions, I think I still prefer the former -- I find it tighter and more self-contained. Besides, the local variable name in the first version is more self-documenting and specific to the test scenario, whereas the name testPanel is more general.
 
Ranch Hand
Posts: 590
6
jQuery Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am searching for this code statement in my project. Current code looks like this.

Did I miss something? invalid coin protection needs to be added. I will check that now.
 
s ravi chandran
Ranch Hand
Posts: 590
6
jQuery Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
current customerpanel.java looks like this:
 
them good ole boys were drinking whiskey and rye singin' this'll be the day that I die. Drink tiny ad.
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
    Bookmark Topic Watch Topic
  • New Topic