From: Arne Vajhøj on
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
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
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
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
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