Mocking/skipping sleep calls in unit tests

What is the general approach in unit tests for methods that involve a sleep() call?

Lets say I have the class:

class Foo {
    public bool someMethodWithSleep() {
        bool failed = false;

        for (int i = 0 : 5) {
            failed = trySomething(); // mocked to return false
            if (failed) {
                TimeUnit.SECONDS.sleep(5);
            } else { return true; }
        }
        return false;
    }
}

In test cases for failures that call this function (directly or nested), I dont want it to sleep for 25+ seconds and slowing every test file that calls it. What’s the best approach to skip the sleep calls in unit tests?

>Solution :

Replace it with a dependency.

class Foo {
    private final Sleeper sleeper;
    public Foo(final Sleeper sleeper) {
        this.sleeper = sleeper;
    }
    public Foo() {
        this(SecondsSleeper.INSTANCE);
    }

    public bool someMethodWithSleep() {
        bool failed = false;

        for (int i = 0 : 5) {
            failed = trySomething(); // mocked to return false
            if (failed) {
                sleeper.sleep(5);
            } else { return true; }
        }
        return false;
    }
}
interface Sleeper {
  void sleep(int duration);
}
enum SecondsSleeper implements Sleeper {
  INSTANCE;
  void sleep(final int seconds) {
    TimeUnit.SECONDS.sleep(seconds);
  }
}
enum TestSleeper implements Sleeper {
  INSTANCE;
  void sleepSeconds(final int duration) {
    // do nothing
  }
}

Then in your real application, create Foo as new Foo() and in your test as new Foo(TestSleeper.INSTANCE)

Leave a Reply