How to Avoid Thread.Sleep in Unit Tests

How to avoid Thread.sleep in Unit tests?

If you are testing [Unit Test] for the method methodToBeTested, you should simply mock routingservice.

You shouldn't be testing any methods that methodToBeTested calls.

However, it sounds like you want to test the RoutingService (you said "The problem is that RoutingService changes the state of objectToRoute and this is exactly what I want to check").

To test RoutingService methods, you should write separate unit tests for those methods.

Avoiding thread.sleep in code while unit testing with Moq

There is probably no way to mock Thread.Sleep because it's a static method and those cannot be mocked with DynamicProxy based mocking Frameworks like moq.

One option would be to use Profiler API based tools like Microsoft Fakes (only in VS Enterprise) or Typemoq professional.

The better option is not to call Thread.Sleep directly in your business logic. What you can do instead is to introduce an Interface like this

public interface ISleepService
{
void Sleep(int ms);
}

Then create a default implementation that you use in your code:

public class SleepService: ISleepService
{
public void Sleep(int ms)
{
Thread.Sleep(ms);
}
}

Add a dependency of ISleepService to your Business Logic

public class MyBusinessLogic()
{
private ISleepService _sleepService;
public MyBusinessLogic(ISleepService sleepService)
{
_sleepService = sleepSerivce;
}

public void MyBusinessMethod()
{
// your code
_sleeService.Sleep(20000);
// more code
}
}

You can then easily mock the ISleepService in your unit tests and pass the real implementation in your production code

UnitTesting a threaded class, avoiding Thread.Sleep() in test?

Basically, you have to apply the Inversion of Control pattern here. Because the code is highly coupled, you are having a problem with testing it.

You should clearly separate all entities and put them against corresponding interfaces. If an entity is used through an interface it is easy to mock it.

public interface ITaskFactory {}
public interface IThreadManager {}
public interface ICollectorDatabase {}
public interface IEventFactory {}

public class FileGroupGarbageCollector
{
ITaskFactory taskFactory;
IThreadManager threadManager;
ICollectorDatabase database;
IEventFactory events;

FileGroupGarbageCollector (ITaskFactory taskFactory,
IThreadManager threadManager, ICollectorDatabase database,
IEventFactory events)
{
// init members..
}
}

As soon as all dependencies are isolated, FileGroupGarbageCollector does not use any of them directly. In your test, the IEventFactory mock will return Event, that would do just nothing if WaitOne method is called. So, you don't need any sleeps in your code.

Go and find as much as you can on - Mocking, Inversion of Control, Dependency Injection patterns.

Java power mock unit test a method having Thread.Sleep

I agree with what @Elevate mentioned, you should not mock the types which you do not own. But if you still have to do it, you can do it like this

@RunWith(PowerMockRunner.class)
@PrepareForTest({<ClassWherewaitForUpscaleFunctionisLocated>.class, Thread.class})
public class Mytest {
@Test
public void testStaticVoid() throws Exception {

PowerMockito.mockStatic(Thread.class);
doNothing().when(Thread.class, "sleep", anyLong());
.........
}
}

How to stop main method calling sleep() method, when testing it with Junit?

There is no easy way for doing this. You have several options.

The easiest one would be to make the REQUEST_STATUS_CHECK_INTERVAL configurable and configure it to 0 in tests. It can be a property of the tested class.

sleep(ofSeconds(getSleepInternval()));

In the test would wold call

testedObject.setSleepInterval(0);

Second option would be to extract the sleep call into it's own class that can be mocked.

class Sleeper {
void sleep(long milisecs) {
Thread.sleep(milisecs);
}
}

In your class you would have

private Sleeper sleeper = new Sleeper(); //nd it's setter, or dependency injection

In the function

sleeper.sleep(ofSeconds(REQUEST_STATUS_CHECK_INTERVAL));

And it the test you can do

Sleeper mockedSleeper = Mockito.mock(Sleeper.class);
testedObject.setSleeper(mockedSleeper);

Unit Test Finishes before Thread.Sleep time

The basic problem is this:

public override void run () {
Thread.Sleep(base.getTimer().Milliseconds);
}

You want to sleep for TotalMilliseconds, not Milliseconds (the Milliseconds component of the TimeSpan - 0 in this case).

That said, speaking more broadly, you just don't want to unit test a method that calls Thread.Sleep, especially not to test the duration of the call. That test will take a long time, be brittle and approximative; 3 properties you absolutely want to avoid in unit tests. To make this code testable, you'd need to abstract the call to Thread.Sleep behind some interface that you can then mock in your unit tests (see dependency injection). Your unit test could have then verified that the value passed to Sleep() was what you expected, and you would have caught this bug without all the problems that testing a real call to Thread.Sleep will cause.

Testing with Thread.sleep

It is usually a good idea to delegate time-related functionality to a separate component. That include getting the current time, as well as delays like Thread.sleep(). This way it is easy to substitute this component with mock during testing, as well as switch to a different implementation.



Related Topics



Leave a reply



Submit