JUnit Test Question

JUnit Test Question

Post by A » Fri, 05 Jul 2002 03:43:49



Hello Everyone.  I would like to preface this question by saying first
that I have read/skimmed the JUnit FAQ before posting :)  Here is the
question/problem:  I have a class that I would like to test using
JUnit.  I cannot test it however, since I do not have access to the
private member variables of the class.  I would rather not just write
accessor methods solely for testing purposes.  This does not seem like
a wholesome solution.  This seems like it would be a common problem.
What should I do in this situation?  Thanks!

AJ

 
 
 

JUnit Test Question

Post by Keith Ra » Fri, 05 Jul 2002 12:43:00




> Hello Everyone.  I would like to preface this question by saying first
> that I have read/skimmed the JUnit FAQ before posting :)  Here is the
> question/problem:  I have a class that I would like to test using
> JUnit.  I cannot test it however, since I do not have access to the
> private member variables of the class.  I would rather not just write
> accessor methods solely for testing purposes.  This does not seem like
> a wholesome solution.  This seems like it would be a common problem.
> What should I do in this situation?  Thanks!

> AJ

This is a common "smell". Too many private methods and private variables
is a sign that the class is too big -- see if you can do Extract Method
to one or more new classes so that you have a few classes instead of
one, and all the methods are public. This group of classes should be
more easily testable.

Occasionally, a 'getter' is useful for testing and for non-test code
too...  For example, 'isEmpty()' helps in testing a stack class, as well
as sometimes being useful to users of a stack class.
--
C. Keith Ray

<http://homepage.mac.com/keithray/xpminifaq.html>

 
 
 

JUnit Test Question

Post by Robert C. Mart » Fri, 05 Jul 2002 23:35:13



Quote:>Hello Everyone.  I would like to preface this question by saying first
>that I have read/skimmed the JUnit FAQ before posting :)  Here is the
>question/problem:  I have a class that I would like to test using
>JUnit.  I cannot test it however, since I do not have access to the
>private member variables of the class.  I would rather not just write
>accessor methods solely for testing purposes.  This does not seem like
>a wholesome solution.  This seems like it would be a common problem.
>What should I do in this situation?  Thanks!

The short answer:  "Make the variables public."

Testability trumps encapsulation.  Think about that for awhile, it's a
no brainer.  Do you want it to work, or do you want the variables
private?

The long answer:

Why do you need to access the private variables in order to test the
class?  Perhaps the design of the class is wrong.  Perhaps there is a
way to separate the class into two or more different classes, each of
which are testable, and yet each of which maintains its encapsulation.

Robert C. Martin  | "Uncle Bob"                  

PO Box 5757       | Tel: (800) 338-6716        
565 Lakeview Pkwy | Fax: (847) 573-1658           | www.objectmentor.com
Suite 135         |                               | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring        | www.junit.org
60061             | OO, XP, Java, C++, Python     |

You and I can enjoy the experience of not always seeing
eye-to-eye, but we can also respect each other, even when
you might find some idea of mine totally ludicrous.
    -- Richard Riehle

 
 
 

JUnit Test Question

Post by AJ » Sat, 06 Jul 2002 01:55:34


Hi Robert. The class is pretty slim-line.  The class (Fix.java) defines a
point on the earth.  There are 4 attributes of a Fix: latitude, longitude,
etc.  The methods themselves are not private, just the member variables.  I
suppose I will go the "public member variable route".  I just started my
career as a software engineer, so I am learning a lot about design that I
never learned in school... The class does some XML parsing on a file to fill
in it's attributes.  These attributes (the private member variables), need
to be tested.  What is the better way of doing this, in addition to making
them public?

Thanks Robert for your insight.

AJ (Newbie to design patterns, XP, and Test-First)

"Uncle Bob (Robert C. Martin)"


> >Hello Everyone.  I would like to preface this question by saying first
> >that I have read/skimmed the JUnit FAQ before posting :)  Here is the
> >question/problem:  I have a class that I would like to test using
> >JUnit.  I cannot test it however, since I do not have access to the
> >private member variables of the class.  I would rather not just write
> >accessor methods solely for testing purposes.  This does not seem like
> >a wholesome solution.  This seems like it would be a common problem.
> >What should I do in this situation?  Thanks!

> The short answer:  "Make the variables public."

> Testability trumps encapsulation.  Think about that for awhile, it's a
> no brainer.  Do you want it to work, or do you want the variables
> private?

> The long answer:

> Why do you need to access the private variables in order to test the
> class?  Perhaps the design of the class is wrong.  Perhaps there is a
> way to separate the class into two or more different classes, each of
> which are testable, and yet each of which maintains its encapsulation.

> Robert C. Martin  | "Uncle Bob"

> PO Box 5757       | Tel: (800) 338-6716
> 565 Lakeview Pkwy | Fax: (847) 573-1658           | www.objectmentor.com
> Suite 135         |                               | www.XProgramming.com
> Vernon Hills, IL, | Training and Mentoring        | www.junit.org
> 60061             | OO, XP, Java, C++, Python     |

> You and I can enjoy the experience of not always seeing
> eye-to-eye, but we can also respect each other, even when
> you might find some idea of mine totally ludicrous.
>     -- Richard Riehle

 
 
 

JUnit Test Question

Post by AJ » Sat, 06 Jul 2002 02:05:38


Thanks for the info Keith.  I am unfamiliar (being a recent college-grad) to
the "Extract Method" philosophy.  I am quessing this is a design pattern of
sorts.  I will take a look into it, should make for some good reading.
Thanks again Keith!

AJ




> > Hello Everyone.  I would like to preface this question by saying first
> > that I have read/skimmed the JUnit FAQ before posting :)  Here is the
> > question/problem:  I have a class that I would like to test using
> > JUnit.  I cannot test it however, since I do not have access to the
> > private member variables of the class.  I would rather not just write
> > accessor methods solely for testing purposes.  This does not seem like
> > a wholesome solution.  This seems like it would be a common problem.
> > What should I do in this situation?  Thanks!

> > AJ

> This is a common "smell". Too many private methods and private variables
> is a sign that the class is too big -- see if you can do Extract Method
> to one or more new classes so that you have a few classes instead of
> one, and all the methods are public. This group of classes should be
> more easily testable.

> Occasionally, a 'getter' is useful for testing and for non-test code
> too...  For example, 'isEmpty()' helps in testing a stack class, as well
> as sometimes being useful to users of a stack class.
> --
> C. Keith Ray

> <http://homepage.mac.com/keithray/xpminifaq.html>

 
 
 

JUnit Test Question

Post by AJ » Sat, 06 Jul 2002 02:06:01


Very nice document, thanks Ilja!

AJ


> > Here is the
> > question/problem:  I have a class that I would like to test using
> > JUnit.  I cannot test it however, since I do not have access to the
> > private member variables of the class.  I would rather not just write
> > accessor methods solely for testing purposes.  This does not seem like
> > a wholesome solution.  This seems like it would be a common problem.

> Yes, it is. You can take a look at

> http://c2.com/cgi/wiki?ExtremeProgrammingTestingPrivateMethods

> Also, searching the JUnit mailinglist archive should reveal a bunch of
> threads about this subject.

> Regards, Ilja

 
 
 

JUnit Test Question

Post by Keith Ra » Sat, 06 Jul 2002 02:43:38




> Thanks for the info Keith.  I am unfamiliar (being a recent college-grad) to
> the "Extract Method" philosophy.  I am quessing this is a design pattern of
> sorts.  I will take a look into it, should make for some good reading.
> Thanks again Keith!

You're welcome.

Check out
 <http://www.refactoring.com> and
 <http://c2.com/cgi/wiki?CodeSmells>
--
C. Keith Ray

<http://homepage.mac.com/keithray/xpminifaq.html>

 
 
 

JUnit Test Question

Post by Robert Chapma » Sat, 06 Jul 2002 02:48:35


I understand what you mean when you talk about the value of testing.
However, I cannot find any way to believe that public variables is a good
solution.  I normally use private member variables that can be retrieved or
set via property of method calls.  Everything I have ever read, going back
to Code Complete, indicates that protecting your data is very important,
public variables violates that tenant.

Would read-only properties solve the OPs problem?  Any thoughts?

Cheers

--
Robert Chapman, MCSD
Manager, Applications Development
prairieFyre Software Inc.
http://www.prairiefyre.com
"Uncle Bob (Robert C. Martin)"


> >Hello Everyone.  I would like to preface this question by saying first
> >that I have read/skimmed the JUnit FAQ before posting :)  Here is the
> >question/problem:  I have a class that I would like to test using
> >JUnit.  I cannot test it however, since I do not have access to the
> >private member variables of the class.  I would rather not just write
> >accessor methods solely for testing purposes.  This does not seem like
> >a wholesome solution.  This seems like it would be a common problem.
> >What should I do in this situation?  Thanks!

> The short answer:  "Make the variables public."

> Testability trumps encapsulation.  Think about that for awhile, it's a
> no brainer.  Do you want it to work, or do you want the variables
> private?

> The long answer:

> Why do you need to access the private variables in order to test the
> class?  Perhaps the design of the class is wrong.  Perhaps there is a
> way to separate the class into two or more different classes, each of
> which are testable, and yet each of which maintains its encapsulation.

> Robert C. Martin  | "Uncle Bob"

> PO Box 5757       | Tel: (800) 338-6716
> 565 Lakeview Pkwy | Fax: (847) 573-1658           | www.objectmentor.com
> Suite 135         |                               | www.XProgramming.com
> Vernon Hills, IL, | Training and Mentoring        | www.junit.org
> 60061             | OO, XP, Java, C++, Python     |

> You and I can enjoy the experience of not always seeing
> eye-to-eye, but we can also respect each other, even when
> you might find some idea of mine totally ludicrous.
>     -- Richard Riehle

 
 
 

JUnit Test Question

Post by Keith Ra » Sat, 06 Jul 2002 03:24:55




Quote:> I understand what you mean when you talk about the value of testing.
> However, I cannot find any way to believe that public variables is a good
> solution.  I normally use private member variables that can be retrieved or
> set via property of method calls.  Everything I have ever read, going back
> to Code Complete, indicates that protecting your data is very important,
> public variables violates that tenant.

> Would read-only properties solve the OPs problem?  

Sure. I would recommend them for the particular problem that the poster
described.

Quote:> Any thoughts?

In an collaborative environment like XP encourages, I trust the
programmers not to do bad things, so I don't always automatically make
variables private immediately.

For example, if a Point class with members x and y doesn't have any
state or behavior that gets screwed up by someone directly poking a new
value into x or y, then I'll make x and y public.

However, if additional state gets put into Point, such as cached
"distance from 0,0" value, then I'll refactor the member variables to be
private, so that "distance" can be recomputed when x or y is changed by
a set method.  [I know this isn't exactly a realistic example.]

I am always on the lookout for objects poking around the insides of
other objects... that's a smell that needs to be corrected.

Lately I've been applying the Pimpl idiom to reduce coupling of .h
files, to improve compile time, etc. This means that not only are member
variables private, they don't even appear in the .h file. So far, I like
it, but refactorings "Move Field" and "Move Method" have a little more
drag when one class is Pimpled and the other is not.
--
C. Keith Ray

<http://homepage.mac.com/keithray/xpminifaq.html>

 
 
 

JUnit Test Question

Post by Robert Chapma » Sat, 06 Jul 2002 05:19:51


Yeah, I can see your point.  If I have a private member called m_FirstName
and a property routine that simply sets it to be the passed value then
m_FirstName may as well be public.  When I find the need to validate
m_FirstName.Length > 0 then it should be refactored into a private member
with a public accessor.  Guess I had forgotten the DTSTTCPW...

Thanks for the input.

--
Robert Chapman, MCSD
Manager, Applications Development
prairieFyre Software Inc.
http://www.prairiefyre.com



> > I understand what you mean when you talk about the value of testing.
> > However, I cannot find any way to believe that public variables is a
good
> > solution.  I normally use private member variables that can be retrieved
or
> > set via property of method calls.  Everything I have ever read, going
back
> > to Code Complete, indicates that protecting your data is very important,
> > public variables violates that tenant.

> > Would read-only properties solve the OPs problem?

> Sure. I would recommend them for the particular problem that the poster
> described.

> > Any thoughts?

> In an collaborative environment like XP encourages, I trust the
> programmers not to do bad things, so I don't always automatically make
> variables private immediately.

> For example, if a Point class with members x and y doesn't have any
> state or behavior that gets screwed up by someone directly poking a new
> value into x or y, then I'll make x and y public.

> However, if additional state gets put into Point, such as cached
> "distance from 0,0" value, then I'll refactor the member variables to be
> private, so that "distance" can be recomputed when x or y is changed by
> a set method.  [I know this isn't exactly a realistic example.]

> I am always on the lookout for objects poking around the insides of
> other objects... that's a smell that needs to be corrected.

> Lately I've been applying the Pimpl idiom to reduce coupling of .h
> files, to improve compile time, etc. This means that not only are member
> variables private, they don't even appear in the .h file. So far, I like
> it, but refactorings "Move Field" and "Move Method" have a little more
> drag when one class is Pimpled and the other is not.
> --
> C. Keith Ray

> <http://homepage.mac.com/keithray/xpminifaq.html>

 
 
 

JUnit Test Question

Post by Ron Jeffrie » Sat, 06 Jul 2002 09:33:43



>Hi Robert. The class is pretty slim-line.  The class (Fix.java) defines a
>point on the earth.  There are 4 attributes of a Fix: latitude, longitude,
>etc.  The methods themselves are not private, just the member variables.  I
>suppose I will go the "public member variable route".  I just started my
>career as a software engineer, so I am learning a lot about design that I
>never learned in school... The class does some XML parsing on a file to fill
>in it's attributes.  These attributes (the private member variables), need
>to be tested.  What is the better way of doing this, in addition to making
>them public?

Making them public is OK. If I were feeling paranoid, I might write getters for
them, with no setters. That way no one could accidentally mess up the
consistency of the class. I might even name the getters with "test" in their
names.

Ronald E Jeffries
http://www.XProgramming.com
http://www.objectmentor.com
I'm giving the best advice I have. You get to decide whether it's true for you.

 
 
 

JUnit Test Question

Post by Robert C. Mart » Sat, 06 Jul 2002 14:32:03


On Thu, 04 Jul 2002 16:55:34 GMT, "AJ"


>I suppose I will go the "public member variable route".

The convention I have used in those rare instances when I have a
variable I want to access from a unit test is:

/* private */ public double myVariable;

Robert C. Martin  | "Uncle Bob"                  

PO Box 5757       | Tel: (800) 338-6716        
565 Lakeview Pkwy | Fax: (847) 573-1658           | www.objectmentor.com
Suite 135         |                               | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring        | www.junit.org
60061             | OO, XP, Java, C++, Python     |

You and I can enjoy the experience of not always seeing
eye-to-eye, but we can also respect each other, even when
you might find some idea of mine totally ludicrous.
    -- Richard Riehle

 
 
 

JUnit Test Question

Post by Robert C. Mart » Sat, 06 Jul 2002 14:35:17


On Thu, 04 Jul 2002 20:33:43 -0400, Ron Jeffries



>>Hi Robert. The class is pretty slim-line.  The class (Fix.java) defines a
>>point on the earth.  There are 4 attributes of a Fix: latitude, longitude,
>>etc.  The methods themselves are not private, just the member variables.  I
>>suppose I will go the "public member variable route".  I just started my
>>career as a software engineer, so I am learning a lot about design that I
>>never learned in school... The class does some XML parsing on a file to fill
>>in it's attributes.  These attributes (the private member variables), need
>>to be tested.  What is the better way of doing this, in addition to making
>>them public?

>Making them public is OK. If I were feeling paranoid, I might write getters for
>them, with no setters. That way no one could accidentally mess up the
>consistency of the class. I might even name the getters with "test" in their
>names.

Or privateGetField();

The word private in the name of a method is a strong indicator that
others shouldn't call it.  It's also grepable.

Robert C. Martin  | "Uncle Bob"                  

PO Box 5757       | Tel: (800) 338-6716        
565 Lakeview Pkwy | Fax: (847) 573-1658           | www.objectmentor.com
Suite 135         |                               | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring        | www.junit.org
60061             | OO, XP, Java, C++, Python     |

You and I can enjoy the experience of not always seeing
eye-to-eye, but we can also respect each other, even when
you might find some idea of mine totally ludicrous.
    -- Richard Riehle

 
 
 

JUnit Test Question

Post by Robert C. Mart » Sat, 06 Jul 2002 14:42:23


On Thu, 4 Jul 2002 13:48:35 -0400, "Robert Chapman"


>I understand what you mean when you talk about the value of testing.
>However, I cannot find any way to believe that public variables is a good
>solution.  I normally use private member variables that can be retrieved or
>set via property of method calls.  Everything I have ever read, going back
>to Code Complete, indicates that protecting your data is very important,
>public variables violates that tenant.

What does 'private' mean?  It means that we don't want others messing
with the variables.  We can achieve that goal by using comments, or by
making the name of the variable indicate privacy.

/*private*/ public double myVariable;

This is pretty clear.  The compiler won't enforce it, but anybody who
wants to use that variable will see the 'private' in front of it, and
realize that they shouldn't mess.  

public double myPrivateVariable;

This is also pretty clear.  In some ways it's better than the comment
convention since anybody who uses is must type 'private' every time
they make use of it.  If they didn't get a guilty conscience about
using the commented variable, they'd likely get one using the
privately named variable.

You may be concerned that the compiler is not able to enforce privacy
in these instances.  However, anybody who really wants to gain access
to a private variable can always do so by one means or another -- so
the compiler enforcement really isn't that valuable.

Yes, I know this flies in the face of a decade of OO dogma, but this
is a particular dogma that I think needs a bit of tuning.  

Robert C. Martin  | "Uncle Bob"                  

PO Box 5757       | Tel: (800) 338-6716        
565 Lakeview Pkwy | Fax: (847) 573-1658           | www.objectmentor.com
Suite 135         |                               | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring        | www.junit.org
60061             | OO, XP, Java, C++, Python     |

You and I can enjoy the experience of not always seeing
eye-to-eye, but we can also respect each other, even when
you might find some idea of mine totally ludicrous.
    -- Richard Riehle

 
 
 

JUnit Test Question

Post by Robert C. Mart » Wed, 10 Jul 2002 02:09:20



>"Uncle Bob (Robert C. Martin)"

>>/*private*/ public double myVariable;

>>This is pretty clear.  The compiler won't enforce it, but anybody who
>>wants to use that variable will see the 'private' in front of it, and
>>realize that they shouldn't mess.  

><shudder>

>This just seems like a giant step backwards.  Why not do away with most
>compiler-caught errors and assume that all programmers will do what the
>original programmer intended?

I agree there is a <shudder> there.  But there is a <SHUDDER> when
someone decides not to write a test simply because a variable is
private.

Given the choice, I'll write the tests and make the variable public.
But, then, I'd always try to find some way to keep the variable
private so long as I can have the test.

Robert C. Martin  | "Uncle Bob"                  

PO Box 5757       | Tel: (800) 338-6716        
565 Lakeview Pkwy | Fax: (847) 573-1658           | www.objectmentor.com
Suite 135         |                               | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring        | www.junit.org
60061             | OO, XP, Java, C++, Python     |

You and I can enjoy the experience of not always seeing
eye-to-eye, but we can also respect each other, even when
you might find some idea of mine totally ludicrous.
    -- Richard Riehle