This question just occurred to my mind and I want to ask this here.
The case is intentional, I just write a loop which runs infinitely. How do I go about unit testing it?
I ask this because, this situation may occur anywhere in the code. Say my method delegates to several other methods, and I want to know
- How it ran into an infinite loop
- What set of input caused it
- Call to which method (from this method) has caused this
I have no code written for this. The question is purely for knowledge sake as to what to do if this situation arises in future. Please respond.
How to unit test a method that runs into an infinite loop for some input?
You can test the nearly opposite: "How to unit test a method so that the method will not run longer than Xxxx milliseconds for some input". If this test fails you may have found a candidate with an infinite loop.
NUnit 2.5 has a TimeoutAttribute that makes a test fail if the test takes longer than the given amount of milliseconds.
I hope you mean some kind of message-pump/event-handling loop. (Most infinite loops are bad).
I'd ensure that the loop delegates to some class which processes the input. Test this class thoroughly.
The probability of a loop construct failing to work is minimal.. So I'd test this out via an acceptance test or manually.
This is somewhat similar to testing the Main function of an executable. The trick here is also to ensure that Main delegates to a testable class.
Have the function that loops delegate the loop check to an injected dependency:
interface IShouldLoop
{
bool ShouldLoop();
}
class ClassToTest
{
private final IShouldLoop shouldLoop;
public ClassToTest(IShouldLoop shouldLoop)
{
this.shouldLoop = shouldLoop;
}
public void MethodToTest()
{
while(shouldLoop.ShouldLoop())
{
// do whatever
}
}
}
You can test that it delegates the loop check to the IShouldLoop
dependency every time, and you can control the looping in your test, so that it only loops the number of times you want. In the production environment, instantiate it with an instance of IShouldLoop
that always returns true.
Purpose of unitesting is to test each most simple unit in your program.
Most simple unit is usually a function which does a single mission, so in order to unitest your infinite Loop you will have to extract each single mission this Loop could do in a seperated function which can be called alone, once done this you will be able to call these functions given them all possible parameter in order to test different szenarios your function should be able to handle. The infinite Loop as a function doesnt have to be unitested, but the smaller missions inside of it.