You test it through separation and/or injection:
// ** WARNING: Untested code
Original
void funcToTest(String a, String b) {
int i = new Random().nextInt(2);
return ((i == 0) ? a : b);
}
Separating
void funcToTest(String a, String b) {
return funcToTest(a, b, (new Random().nextInt(2) == 0));
}
void funcToTest(String a, String b, boolean r) {
return (r ? a : b);
}
Now test
funcToTest(String a, String b, boolean r).
You're trusting that, if you test the above, then
funcToTest(String a, String b)
will work just work.
Injecting
interface BoolRandomizer {
bool getBool();
}
BoolRandomizer BOOL_RANDOMIZER = new BoolRandomizer() {
public bool getBool() { return (new Random().nextInt(2) == 0); }
}
BoolRandomizer ALWAYS_FALSE_RANDOMIZER = new BoolRandomizer() {
public bool getBool() { return false; }
}
BoolRandomizer ALWAYS_TRUE_RANDOMIZER = new BoolRandomizer() {
public bool getBool() { return true; }
}
class ClassUnderTest {
private final BoolRandomizer br;
ClassUnderTest() { this(BOOL_RANDOMIZER); }
ClassUnderTest(BoolRandomizer br) { this.br = br; }
void funcToTest(String a, String b) {
return (br.getBool() ? a : b);
}
}
Now test
new ClassUnderTest(ALWAYS_FALSE_RANDOMIZER).funcToTest()
and
new ClassUnderTest(ALWAYS_TRUE_RANDOMIZER).funcToTest()
There are of course more complex/slicker ways to do this, but this is the basic idea. I used these techniques for a deck of cards program to test the shuffle function. Another case: a function that uses current time by calling system API gettime() could be hard to test unless you are willing to run the unit test at very specific times of day :-). Separation and injection ease testing.