From: Arne Vajhøj on 18 Mar 2010 22:00 On 18-03-2010 15:38, Eric Sosman wrote: > On 3/18/2010 3:22 PM, Rhino wrote: >> I think I understand the basics of using JUnit - I'm still using JUnit3 >> for the moment - but I want to ask some things that I don't find clear in >> the documentation that I've found. >> >> Would it be reasonable to say all of the following? >> >> 1. For each class that I develop, I should have one JUnit class that >> extends TestCase and that this TestCase class should test each of the >> methods in the class I developed? > > Sort of, I'd say. Private and even package-private classes > might get a waiver, the idea being that their "contracts" are only > with the public classes that "employ" them. Non-public nested > classes, same thing: If they're really just "implementation details" > of their containing classes, they might not need separate testing. > (For some inner classes, it won't be possible to test in isolation.) > > "Each method" may be a overkill, too. Getters and setters come > to mind as "too simple to test" -- usually. I recommend testing them as well. They are easy to test and weird things have been seen in code before. Arne
From: Eric Sosman on 18 Mar 2010 23:53 On 3/18/2010 10:00 PM, Arne Vajh�j wrote: > On 18-03-2010 15:38, Eric Sosman wrote: >> On 3/18/2010 3:22 PM, Rhino wrote: >>> I think I understand the basics of using JUnit - I'm still using JUnit3 >>> for the moment - but I want to ask some things that I don't find >>> clear in >>> the documentation that I've found. >>> >>> Would it be reasonable to say all of the following? >>> >>> 1. For each class that I develop, I should have one JUnit class that >>> extends TestCase and that this TestCase class should test each of the >>> methods in the class I developed? >> [...] >> "Each method" may be a overkill, too. Getters and setters come >> to mind as "too simple to test" -- usually. > > I recommend testing them as well. > > They are easy to test and weird things have been seen in code before. Well, I *did* say "usually." If setters are supposed to do something more than merely set a value -- fire change events, say, or recompute allied values other than the ones directly set -- that's worth testing. If getters return arrays, it's worth verifying that mucking with the returned array doesn't magically modify the state of the object it came from (unless it's supposed to, in which case one should test that it actually does). And so on, and so on. But I put it to you that public void setScrew(int screw) { this.screw = screw; } .... is more amenable to verification by inspection than by test. As to ease of testing, I note that the code to test a simple getter or setter is more complex than the code tested; something seems fundamentally wrong with this. If we think a one-liner needs testing, why aren't we writing tests for the umpteen-line test class? -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Daniel Pitts on 19 Mar 2010 01:40 On 3/18/2010 5:44 PM, Eric Sosman wrote: > On 3/18/2010 5:13 PM, Jim wrote: >> On Thu, 18 Mar 2010 15:38:05 -0400, Eric Sosman >> <esosman(a)ieee-dot-org.invalid> wrote: >>> [...] >>> "Each method" may be a overkill, too. Getters and setters come >>> to mind as "too simple to test" -- usually. I've never heard of >>> anyone writing a unit test for the hashCode()/equals() pair (their >>> agreement should be verified, but it's not clear that testing is >>> the best way to go about it). >> <snip> >> >> Have to disagree about equals() at least. Having a unit test for >> equals ensures that when you make changes to your class you >> don't break the method. As me how I know ;-) > > Sorry if I wasn't clear: By referring to the "pair," I meant > trying to test that x.equals(y) -> x.hashCode() == y.hashCode(), > or that x.hashCode() != y.hashCode() -> !x.equals(y). Testing > equals() alone may make sense. Testing hashCode() alone almost > certainly doesn't. The implications must hold, but I'm not > convinced testing is the right way to verify that they do. > if your objects behavior depends on correct functioning of that method pair, then you should definitely unit test them. At the very least, testing the first is important (x.equals(y) -> x.hashCode() == y.hashCode()). Actually, if you test that for all edge/general cases, then the second one is probably irrelevant (or redundant) -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Tom Anderson on 19 Mar 2010 07:23 On Thu, 18 Mar 2010, Rhino wrote: > Eric Sosman <esosman(a)ieee-dot-org.invalid> wrote in > news:hntvh4$hho$1(a)news.eternal-september.org: > >> On 3/18/2010 3:22 PM, Rhino wrote: >>> I think I understand the basics of using JUnit - I'm still using >>> JUnit3 for the moment - but I want to ask some things that I don't >>> find clear in the documentation that I've found. >>> >>> Would it be reasonable to say all of the following? >>> >>> 1. For each class that I develop, I should have one JUnit class that >>> extends TestCase and that this TestCase class should test each of the >>> methods in the class I developed? >> >> "Each method" may be a overkill, too. Getters and setters come >> to mind as "too simple to test" -- usually. I've never heard of >> anyone writing a unit test for the hashCode()/equals() pair (their >> agreement should be verified, but it's not clear that testing is >> the best way to go about it). > > I had a feeling that question was going to be a bit controversial ;-) > > I asked a similar question a few weeks back and some people said that > you should test absolutely everything, even seemingly trivial code like > getters/setters. I don't recall ever having a bug in anything quite that > trivial so I'm still a little dubious about the merit of testing really > simple code I'm not religious about this either. In particular, i often don't test all trivial convenience constructors. If i have: class CombineHarvester { public CombineHarvester(int horsepower, HeadType head) { // ... } public CombineHarvester(int horsepower) { this(horsepower, HeadType.GRAIN_PLATFORM); } } I might not test the second constructor. However, you often test getters and setters in the course of testing other methods. For example: @Test testOverdraftLimit() { Account ac = new Account(); ac.setBalance(100000); ac.setOverdraftLimit(20000); int withdrawn = ac.withdraw(150000); assertEqual(120000, withdrawn); assertEqual(-20000, ac.getBalance()); } That method is ostensibly about testing the overdraft limit logic, but it depends on setBalance and getBalance working right. If they don't, it will break, and you'll find out about it. Well, or they'll mask a bug in the overdraft mechanism, and you won't find out about either bug, but that's life. tom -- Where yesterday's future is here today
From: Graham Cox on 19 Mar 2010 08:17
Rhino <no.offline.contact.please(a)example.com> writes: > I've been lucky enough not to get burned by one of those yet - at least as > far as I know! - but you make a good point. Murphy's Laws, right? Anything > that can go wrong, will go wrong. > > It probably makes sense to test even really trivial-looking code.... > I tend to think that any function with more than 2 lines of code should be unit tested. This means that getters and setters are generally exempt *unless they do something*. Specifically it means that the setters that do data validation first should be tested, but the setters that do nothign more than store the value to a member variable can be ignored... -- Graham Cox |