RE: Testing a class which utilizes randomness

"Donaldson, John" <[email protected]> Fri, 4 Apr 2014 14:49:45 +0000
Newsgroups gmane.comp.programming.test-driven-development
Message-ID <716D07F3CBA94244A0922E7A99837C3A13B3F037@G5W2731.americas.hpqcorp.net>
Nikola,

In this case, you have two things happening: random strings, and unique strings.

Let's suppose your unique random string generator is called UniqueStringGenerator.
You need to inject the random generator - don't embed it in the class itself - in this way you can control what is generated when needed (in your test).

For example your constructor might say: public UniqueStringGenerator ( IRandomGenerator randomGenerator).
Then you need to create the interface IRandomGenerator. There will be a method something like getRandom() or something similar.

In your duplicate name test, create a DuplicateTestRandomGenerator object which implements IRandomGenerator.
In DuplicateRandomTestGenerator just return the same random string from getRandom().
Inject it into the UniqueStringGenerator.
Run your test.

Of course, when you want to really use UniqueStringGenerator, you instantiate it with an object which implements IRandomGenerator - but which really generates random strings.
The real RandomGenerator gets tested in other tests.

So, two principals:

-          Inject things which you need to control them for testing (random number generators or clocks for example)

-          Separate responsibilities: the UniqueStringGenerator is only responsible for handing out a unique string (it will check against previously generated strings). The RandomGenerator is only responsible for generating a random string.

Hmm! More writing than I expected. I hope it's clear.

John D.

From: [email protected] [mailto:[email protected]] On Behalf Of Nikola Novak
Sent: 04 April 2014 11:29
To: [email protected]
Subject: [TDD] Testing a class which utilizes randomness




Hello!

I'm new to TDD and this group. For practice, I started a simple project and now I want to create a list of random strings, but such that no two strings are ever the same. In a very unlikely, yet possible case, when two randomly generated strings are the same, the method that does this should discard the duplicate and generate a new string before it returns.

What I want to test is exactly this behavior - the code which discards the duplicate and forces the string to be regenerated. To test that, I need to force the random string generator to return a duplicate at least once (but finite number of times). To create the test which would generate strings until there's at least one duplicate is unrealistic, because such a test could take a very long time to complete.

How would I write such a test?

Kind regards,
Nikola