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
Java.Lang.Noclassdeffounderror: Com/Fasterxml/Jackson/Databind/Exc/Invaliddefinitionexception
Update Elements in a Jsonobject
How to Use Different Jsonproperty on Serialize & Deserialize Using Jackson API
Scheduling a Job With Spring Programmatically (With Fixedrate Set Dynamically)
Setting Default Values to Null Fields When Mapping With Jackson
Determine the Number of Pages in a Pdf File
Avoid Keycloak Default Login Page and Use Project Login Page
How to Convert Xml to Java.Util.Map and Vice Versa
Filling a List With All Enum Values in Java
Adb Cannot Connect to Daemon At Tcp:5037
Check If Url Is Https or Http Protocol
Checking If a String Contains a Dot
Reading Data from Nested Json Object Using Java
How to Generate a Unique and Short File Name in Java
How to Read Empty Cells of an Excel File Using Poi
How to Efficiently Read Multiple Json Files into a Dataframe or Javardd