JUnit4 : Test a shutdown hook is called - java

I have a method which adds a shutdown hook. I need to test (via JUnit) that the code executed in the hook is called :
public void myMethod(){
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
... code to test ...
}
});
}
How can I simulate a shutdown in my unit test ?

I don't think you'll be able to test that. Instead, just test that your code behaves correctly when invoked (by unit testing it separately). Then, trust that Java will invoke your code at the right time.
I.e. extract your code into a separate class that extends Thread and test the behaviour by executing run() in a unit test.

In addition to Duncans answer I'd like to point out the Runtime.getRuntime().removeShutdownHook(Thread) method. Its boolean return value indicates if the respective thread was a registered hook previously.
Thus, one can test if the hook' run() method performs correctly as one part of a test.
As a second part one can call Runtime.getRuntime().removeShutdownHook(Thread)` and assert that the thread was actually registered as a hook.
Together, the two tests assure the overall functioning of the shutdown hook.

Related

Cucumber hooks execute after all feature scenarios ended

I try to execute a script to clean up db after features executions in cucumber.
I use the before and after hook in the following fashion:
private static boolean skipActions = false;
#Before("#initData")
public void setupData() throws Exception {
if (!skipActions) {
initData();
skipActions = true;
}
}
for the before I can avoid the script to be called before each scenario using a static variable. But didn't figure out how to do it for the after hook:
#After("#clearData")
public void tearDown() throws Exception {
clearData();
}
is there a way to capture if the last scenario has executed and trigger clearData() only if that condition is fulfilled ? Is there a more elegant way of doing it ?
So in ruby there is an at_exit hook. but this isn't cucumber, it's programmatically related. I would look inside your language to see if this is possible.
Failing that, you can store a class variable during your run of the number of failures. then if all of those have passed then you can do something.
Another way you could tackle it would be to wrap your execution job in something like jenkins, jenkins has nice simple out of the box methods for cleaning things up.
In Jenkinsfile's both declarative and scripted pipelines allow the calling of cleanWs() as a groovy statement which then wipes the entire jenkins node.

Best Way to Write Unit Test for Code Using Thread.sleep

I want to write unit tests to test if the code calls thread.sleep only when certain condition is met. Also this method is called by a framework which has the retry logic so I also want to test a case where the thread is interrupted and the code would work as expected. I figured out a way to wrap the Thread.Sleep() in a wrapper class and mock that class to see if the method is called or throw exception for unit test. But I feel it's a overkill to have a wrapper class of thread sleep just for unit tests. Is there a better way to acheieve the same purpose without a wrapper class?
public long sendMessageToDownStream(final Message message) throws StopgapDDBException, InterruptedException {
if (message.meetCertainCondition()) {
Thread.sleep(TimeUnit.SECONDS.toMillis(msReadFromConfig));
}
//send message to downstream and get messageId.
messageId = downStream.return();
return messageId;
}

Run Spring class asynchronously

I'm working in an Spring application that downloads data from different APIs. For that purpose I need a class Fetcher that interacts with an API to fetch the needed data. One of the requirements of this class is that it has to have a method to start the fetching and a method to stop it. Also, it must download all asynchronously because users must be able to interact with a dashboard while fetching data.
Which is the best way to accomplish this? I've been reading about task executors and the different annotations of Spring to schedule tasks and execute them asynchronously but this solutions don't seem to solve my problem.
Asynchronous task execution is what you're after and since Spring 3.0 you can achieve this using annotations too directly on the method you want to run asyncrhonously.
There are two ways of implementing this depending whether you are interested in getting a result from the async process:
#Async
public Future<ReturnPOJO> asyncTaskWithReturn(){
//..
return new AsyncResult<ReturnPOJO>(yourReturnPOJOInstance);
}
or not:
#Async
public void asyncTaskNoReturn() {
//..
}
In the former method the result of your computation conveyed by yourReturnPOJOInstance object instance, is stored in an instance of org.springframework.scheduling.annotation.AsyncResult<V> which in return implements the java.util.concurrent.Future<V> that the caller can use to retrieve the result of the computation later on.
To activate the above functionality in Spring you have to add in your XML config file:
<task: annotation-driven />
along with the needed task namespace.
The simplest way to do this is to use the Thread class. You supply a Runnable object that performs the fetching functionality in the run() method and when the Thread is started, it invokes the run method in a separate thread of execution.
So something like this:
public class Fetcher implements Runnable{
public void run(){
//do fetching stuff
}
}
//in your code
Thread fetchThread = new Thread(new Fetcher());
fetchThread.start();
Now, if you want to be able to cancel, you can do that a couple of ways. The easiest (albeit most violent and nonadvisable way to do it is to interrupt the thread:
fetchThread.interrupt();
The correct way to do it would be to implement logic in your Fetcher class that periodically checks a variable to see whether it should stop doing whatever it's doing or not.
Edit To your question about getting Spring to run it automatically, if you wanted it to run periodically, you'll need to use a scheduling framework like Quartz. However, if you just want it to run once what you could do is use the #PostConstruct annotation. The method annotated with #PostConstruct will be executed after the bean is created. So you could do something like this
#Service
public class Fetcher implements Runnable{
public void run(){
//do stuff
}
#PostConstruct
public void goDoIt(){
Thread trd = new Thread(this);
trd.start();
}
}
Edit 2 I actually didn't know about this, but check out the #Async discussion in the Spring documentation if you haven't already. Might also be what you want to do.
You might only need certain methods to run on a separate thread rather than the entire class. If so, the #Async annotation is so simple and easy to use.
Simply add it to any method you want to run asynchronously, you can also use it on methods with return types thanks to Java's Future library.
Check out this page: http://www.baeldung.com/spring-async

Stop Testng test from beforeInvocation method

Can I "stop" running test from beforeInvocation method of IInvokedMethodListener2?
I do some kind of soft skip with "throw new SkipException" in beforeInvocation, but I need to do "hard skip" - stop test without any trace of execution.
I first need to check some test method's annotations and then run or not run that specific test.
Thanks ...
Throwing new SkipException in IInvokedMethodListener2.beforeInvocation() yields the same result (and report) as for a test depending on a failed test: test method makes into the report and is duly marked as skipped. So the test method does not get executed.
If it's not hard enough, I'd recommend test exclusion, not skipping. There is
BeanShell expression feature to run custom inclusions and exclusions.
Also, IAnnotationTransformer would allow you to disable (equivalent of "enabled=false" attribute) a test method at runtime, the simplest example being:
public class SkippingTransformer implements IAnnotationTransformer {
#Override
public void transform(ITestAnnotation ita, Class type, Constructor c, Method method) {
if(method.getName().startsWith("skipMe")) {
ita.setEnabled(false);
}
}
}
This will opt out test methods completely (that is, test count reduces).
But you'll most likely need to take care of disabling chains of dependent methods. There may be other aspects to consider.

How can I make JUnit 4.8 run code after a failed test, but before any #After methods?

I'm driving a suite of Selenium tests (actually WebDriver-backed Selenium) using JUnit 4.8.2. I'd like the tests to automatically take a screenshot of the browser as soon as the test fails an assertion. All the tests inherit from SeleniumBaseTestCase, and the majority then further inherit from from SeleniumBastTestCaseWithCompany (which uses #Before and #After methods to create and then clean up common test data via Selenium).
I've tried adding a subclass of TestWatchman as a #Rule in SeleniumBaseTestCase, overriding TestWatchman's failed method to take the screenshot. The trouble is that the #After methods cleaning up the test data are being run before TestWatchman's failed method is called, so the screenshots are all of the final step of the clean-up, not the test that failed.
Looking into it a little, it seems that TestWatchman's apply method just calls the passed Statement's evaluate method (the only exposed method), which calls the #After methods, leaving TestWatchman (or any other Rule) no chance to insert any code between the execution of the test and of the #After methods, as far as I can tell.
I've also seen approaches that create a custom Runner to alter the Statements created so that methods annotated with the custom #AfterFailure are run before #After methods (so the screenshot can be taken in such an #AfterFailure method), but this relies on overriding BlockJUnit4ClassRunner's withAfters method, which is deprecated and due to become private, according to the documentation, which suggests using Rules instead.
I've found another answer on SO about the #Rule lifecycle that makes it sound like this simply might not be possible in JUnit 4.8, but may be possible in JUnit 4.10. If that's correct then fair enough, I'd just like confirmation of that first.
Any thoughts on an elegant and future-proof way in which I can achieve what I want would be much appreciated!
You are right in your analysis, #Befores and #Afters are added to the list of Statements before any Rules. The #Before gets executed after the #Rule and the #After gets executed before the #Rule. How you fix this depends on how flexible you can be with SeleniumBaseTestCaseWithCompany.
The easiest way would be to remove your #Before/#After methods and replace them with an ExternalResource. This could look something like:
public class BeforeAfterTest {
#Rule public TestRule rule = new ExternalResource() {
protected void before() throws Throwable { System.out.println("externalResource before"); }
protected void after() { System.out.println("externalResource after"); }
};
#Test public void testHere() { System.out.println("testHere"); }
}
this gives:
externalResource before
testHere
externalResource after
This field can be put into your base class, so it gets inherited/overridden. Your problem with ordering between #After and your rules then goes away, because you can order your rules how you like, using #RuleChain (in 4.10, not 4.8).
If you can't change SeleniumBaseTestCaseWithCompany, then you can extend BlockJUnit4ClassRunner, but don't override withAfters, but override BlockJUnit4ClassRunner#methodBlock(). You can then call super.methodBlock, and reorder the Statements as necessary[*].
[*]You could just copy the code, and reorder the lines, but withRules is private and therefore not callable from a subclass.

Categories

Resources