views:

74

answers:

3

I am unit testing a class with a property whose value changes often, depending on communication it receives from another component. If the class does not receive any communication for 5 seconds, the property reverts to a default value.

It is easy for me to stub and mock out the communicating component in order to trigger the values I want to test for. The problem is that if I run my unit tests on a machine which is busy (like a build machine), and there is a significant-enough delay to cause the property to default, then my unit test will fail.

How would you test to be sure that this property has the proper value when simulating various communication conditions?

One idea is to restructure my code so that I can stub the part of the class which controls the timeout. Another is to write my unit test such that it can detect if it failed due to a timeout and indicates that in the test results.

+3  A: 

You could make the timeout property configurable, then set it to a high enough value in your unit tests (or low enough, if you want to unit test the reset behaviour).

Péter Török
I chose to go this route because it was the simplest solution for my situation. The other suggestions were great as well. Thanks all!
emddudley
+2  A: 

There is the same comon problem when using DateTime.Now. Ayende described a trick to deal with it that I liked :

public static class SystemTime
{
    public static Func<DateTime> Now = () => DateTime.Now;
}

and then in your test :

[Test]
public void Should_calculate_length_of_stay_from_today_when_still_occupied()
{
    var startDate = new DateTime(2008, 10, 1);
    SystemTime.Now = () => new DateTime(2008, 10, 5);

    var occupation = new Occupation {StartDate = startDate};

    occupation.LengthOfStay().ShouldEqual(4);
}

Maybe You can leverage the same kin trick for your Timeout?

Stephane
+1 Interesting.
emddudley
+4  A: 

I'd try a different approach. Game developers often need a way to control the game time, e.g. for fast-forward functionality or to synchronize frame rates. They introduce a Timer object, which reads ticks from either a hardware clock, or from a simulated clock.

In your case, you could provide a controllable timer for your unit tests and a timer which delegates to system time in production mode. That way, you can control the time which passes for your test case and thus how the class-under-test has to react under certain timeout conditions.

Pseudo-code:

public void testTimeout() throws Exception {
  MockTimerClock clock = new MockTimerClock();

  ClassUnderTest cut = new ClassUnderTest();
  cut.setTimerClock(clock);
  cut.beginWaitingForCommunication();

  assertTrue(cut.hasDefaultValues());
  cut.receiveOtherValues();
  assertFalse(cut.hasDefaultValues());

  clock.tick(5,TimeUnit.SECONDS);
  assertTrue(cut.hasDefaultValues());
  cut.shutdown();
}
mhaller