Creating a unit test in vs2008 for an object that holds strings?

  • Thread starter Thread starter Andy B
  • Start date Start date
A

Andy B

I have a class called Address. It holds strings to represent different parts
of an address (street, city, state, zipCode). It doesn't really have
anything in it other than a blank constructer and some default properties to
set and get the string values. How would you write tests on this class to
make sure everything is running ok? Or are tests on something like a string
container like this not really useful? Let me know what some ideas are. The
thing that would be tested for is that there are only strings being saved in
the container and nothing else. I thought of even putting a constructer to
create the address itself instead of having to assign every property.
 
I have a class called Address. It holds strings to represent different parts
of an address (street, city, state, zipCode). It doesn't really have
anything in it other than a blank constructer and some default properties to
set and get the string values. How would you write tests on this class to
make sure everything is running ok? Or are tests on something like a string
container like this not really useful? Let me know what some ideas are. The
thing that would be tested for is that there are only strings being saved in
the container and nothing else. I thought of even putting a constructer to
create the address itself instead of having to assign every property.

If all it does is store whatever values its given, I'd say that it's
not worth writing something to test it. Save your time to code tests
for complex things, actual business rules, etc.
 
That's kind of what I figured, but thought I would put it out here in case I
was wrong somehow.
 
Andy said:
That's kind of what I figured, but thought I would put it out here in
case I was wrong somehow.

As long as this type is used in the public methods of other types you do
have unit tests for, it will be tested as a side effect of those other
tests.
 
What do you mean? So, your saying that if I used the Address type as a
parameter to another method that gets tested, then the address gets tested
anyways?

Guess there's not much logic to an address eh? sounds kind of funny...
 
Andy said:
I have a class called Address. It holds strings to represent different parts
of an address (street, city, state, zipCode). It doesn't really have
anything in it other than a blank constructer and some default properties to
set and get the string values. How would you write tests on this class to
make sure everything is running ok? Or are tests on something like a string
container like this not really useful? Let me know what some ideas are. The
thing that would be tested for is that there are only strings being saved in
the container and nothing else. I thought of even putting a constructer to
create the address itself instead of having to assign every property.

It depends.

The biggest reason for writing tests is to allow somebody else (or you)
to refactor your code and easily tell if they have broken it.

Another reason is that it clearly documents how the class should be used.

Lets say you decide to validate Zip Codes against States... If you have
unit tests, you can easily tell if you have broken the basic behavior.
If you don't have tests, you might introduce bugs in the process.

However, tests are not always a good thing. In this case, they could get
brittle and slow the development process (since, for example, you might
refactor Address away entirely, pull it in from a database, etc).

Unit tests cost time. Bugs cost time. Write the unit tests if they cost
less than the bugs. Let the bugs happen if they cost less than the unit
tests (eg. If you're writing a *truely* throwaway app).

If in doubt, I'd write tests.


And if you're writing so many of these types of classes that you need to
care about whether they need tests, you probably need to rethink your
architecture.

Alun Harford

</long, winding post>
 
What is a throw away app? and I didn't know how to make a serializable
object, so I made an xsd file and ran it through xsd not knowing what it
would come up with...guess that can kind of get you in trouble ...
 
Andy said:
What do you mean? So, your saying that if I used the Address type as a
parameter to another method that gets tested, then the address gets
tested anyways?

Yes. If the only "behavior" of the Address class is to carry data to/from
other classes, then that's all you need to test, and the unit tests of the
other class do that.
 
Andy said:
I have a class called Address. It holds strings to represent different parts
of an address (street, city, state, zipCode). It doesn't really have
anything in it other than a blank constructer and some default properties to
set and get the string values. How would you write tests on this class to
make sure everything is running ok? Or are tests on something like a string
container like this not really useful? Let me know what some ideas are. The
thing that would be tested for is that there are only strings being saved in
the container and nothing else. I thought of even putting a constructer to
create the address itself instead of having to assign every property.

If you only use some getters/setters on this class i wouldn't spend much
time on unit tests. however, the described class could be improved
considerably.

i would implement it as an immutable type with only getters and a
constructor. this would reduce the problem you have when you change the
zip-code but not the city and the state. remember, even when you change
them one after the other the state of your instance is incorrect during
the modifications. furthermore your type will not be thread-safe.

you will need some rules to verify that zip-code and city actually match
and to ensure that the zip code is in the correct format. so, you
eventually will implement business-rules on this type ...

now, if you add the rules to your setters you'd get some silly
exceptions if the zip doesn't match the city (when changing the zip
after the city) or vice versa.

so, make the type immutable, create business-rules and verify them and
finally test them.

Alain
 
you will need some rules to verify that zip-code and city actually
match and to ensure that the zip code is in the correct format. so,
you eventually will implement business-rules on this type ...

now, if you add the rules to your setters you'd get some silly
exceptions if the zip doesn't match the city (when changing the zip
after the city) or vice versa.

so, make the type immutable, create business-rules and verify them and
finally test them.

You're in for a world of hurt if you try to write rules to validate postal
codes. (pun intended)
 
Um... what does this mean? It is part of a larger class that will get
written to an xml file. The last I knew of, XmlSerializer.Serialize required
that the properties to be written be read/write. Any readonly properties got
ignored? Am I wrong with this?
immutable? this is the first time I heard of such a thing in programming.
What is it and how do you use it?
 
Andy said:
Um... what does this mean? It is part of a larger class that will get
written to an xml file. The last I knew of, XmlSerializer.Serialize required
that the properties to be written be read/write. Any readonly properties got
ignored? Am I wrong with this?
immutable? this is the first time I heard of such a thing in programming.
What is it and how do you use it?

try this for a start
http://winfxworld.spaces.live.com/Blog/cns!763BFEA85DD32432!177.entry

regards
alain
 
Alain said:
well, there is a world outside US ;-)

That's exactly my point. It's effectively impossible to write rules to
accept any valid address (except the trivial one, which permits anything at
all, and is what you recommended that the OP change).
 
Ben said:
That's exactly my point. It's effectively impossible to write rules to
accept any valid address (except the trivial one, which permits anything at
all, and is what you recommended that the OP change).

my main recommendation was to make the type immutable and i stick to
that. you could for instance add a rule that zip code only contain
characters a-Z and 0-9 or only numbers or whatever. the same is true for
cities where numbers and special characters are not allowed. these are
simple rules and i'd recommend to implement and test them.

if the type is not immutable it is actually possible to get wrong addresses.
 
my main recommendation was to make the type immutable and i stick to
that. you could for instance add a rule that zip code only contain
characters a-Z and 0-9 or only numbers or whatever. the same is true for
cities where numbers and special characters are not allowed. these are
simple rules and i'd recommend to implement and test them.
That wasn't the original issue. Business rules are in a different section of
the code than the object itself. Testing if addresses were actually valid
wasn't the thing. What was needed, was a yes or no type of answer on whether
or not a string container like an address type should be tested to see if
there was any problems with its ability to hold and retain the raw strings
that it was given.
if the type is not immutable it is actually possible to get wrong
addresses.
How is this possible? If you do something like:

Address Address = new Address();
Address.City = "A city";

I guess I just don't get how you can say that if "a city" is given to
address.city, how that could eventually be the wrong city name?
 
Andy said:
I have a class called Address. It holds strings to represent different parts
of an address (street, city, state, zipCode). It doesn't really have
anything in it other than a blank constructer and some default properties to
set and get the string values. How would you write tests on this class to
make sure everything is running ok? Or are tests on something like a string
container like this not really useful? Let me know what some ideas are. The
thing that would be tested for is that there are only strings being saved in
the container and nothing else. I thought of even putting a constructer to
create the address itself instead of having to assign every property.

To be honest I'm a bit ambivalent to this question.

On one hand I advocate testing everything, for various reasons (I'm
getting to those), but on the other hand, a class that holds strings
(struct with fields?), do you really foresee much problems in creating
that class?

My goal for 100% tests is to be able to do code coverage that ends up in
100% coverage. If you can attain that, it's easy to figure out what
parts of your code you're missing a test for, you can just run code
coverage.

On the other hand, I also advocate writing the tests first, so that you
can afterwards check that the class functions according to specifications.

But, if you don't want to, or can't, go to 100% code coverage for unit
tests, you should prioritize your tests, so that you don't spend time
writing tests for one class that really should've been spent on writing
tests for another more important class.

Basically, for each class/code blocks/testable unit, you should decide
on the following two criteria:

1. what is the risk of this code being wrong?
2. what is the consequence of this code being wrong?

If the answer to the above questions are:

1. low
2. little

then write the test to it last.

If on the other hand the answers are:

1. medium to high (complex class)
2. critical showstopping bug (payment system down, ordering system
producing the wrong orders, etc.)

then by all means, test it to death.

To me, it sounds like your class belongs in the first category. Not much
that can go wrong. It might have dire consequences if it goes wrong, but
you also need to decide on what could go wrong. If one thing that could
go wrong was that a field of the class was null, and this could crash
your app with a null reference exception, then it would depend on the
application wether this was "critical" or not.

I don't think anyone but you yourself can really decide wether the class
is worthy of its own test or not.

Personally I would write a test for it, but it would be written towards
the end of the project, given enough time to do it, at least with what
you've told us about it so far.
 
I can't reveal all of the details of the Contract object for security
reasons, but it does make use of 18 other objects and data types that have
been created for the Contract object's sole use. So, The Contract object
"owns" 18 other objects/data types. And of course, the Contract object
itself + the other 18 objects/data types it owns has other fields and
properties of different data types. It seems to be quite complex, but the
main purpose of the Contract object is to hold and store validated data that
makes up the actual Contract document and all of its parts. The Contract
object also holds different states of the Contract itself (Signed, Fulfilled
and so on). Would this Contract class need to have it's test written before
the creation of it? or do you think it can wait until the code for the
object has been written first.
 
Andy said:
How is this possible? If you do something like:

Address Address = new Address();
Address.City = "A city";

you have to threads A and B and both access the same address. thread A
changes the address
from
address.City = "Zurich";
adress.ZipCode = "8000";
to
address.City = "Berne";
adress.ZipCode = "3000";

When thread B accesses the instance between the change of zipCode and
City it would get
address.City = "Berne";
adress.ZipCode = "8000";

although the object looks ok and no rules prohibit this, the address is
actually wrong. with an immutable type thread B would get an old, but
correct address, until the new address is available completely.
 
Alain said:
If you only use some getters/setters on this class i wouldn't spend much
time on unit tests.

Believe it or not, but I have actually seen getters and setters
being wrong after too much copy paste (it was not C# but that does
not really matter).

As a consequence I am paranoid enough to even make unit tests
for that type of class.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top