Unit testing of non-blocking method (asynchronous testing)

I have a very simple Check class that has a waitForCondition() blocking method. This method blocks. I want to create some unit tests for this method. First, the method should return when the condition is met. Secondly, the method should return when it is interrupted.

Internally, the Check class has an ArrayBlockingQueue and calls its take() method, so my test really deals with the correct encoding of the logic for the condition (as it should be). In the application, data for the Check class is supplied by another stream through the InputData method. The InputData method executes the logic of the input data and places the dummy object in the ArrayBlockingQueue when the condition is met. This should return waitForCondition() .

So, my first thought: I can check the InputData , taunting and checking that the dummy object is added to the queue when the condition is met. This would require a redesign of the class, since the queue is a private member of the data (unless it is possible to deride private data). Instead of InputData , adding directly to the queue when the condition is met, it would have to call something that could be taunted.

But then the problem arises of checking the waitForCondition() methods themselves, provided that InputData working correctly. This is really just code:

 try { myArrayBlockingQueue.take(); return true; } catch (InterruptedException ex) { return false; } 

So, I am wondering if this problem should be imagined: a test that creates another thread with Check calls waitForCondition() , and then returns something when it is done. Perhaps using the Contractorโ€™s service. The fuzzy part is the assertTrue(...) synchronization assertTrue(...) . I found this article on asynchronous testing , which looks like it could do the trick.

Question Summary:

  • Should I change the design to check the logic in InputData() , and if so, how?
  • Should I leave the waitForCondition() test as long as InputData() is being tested?
  • Or is it better to just do what needs to be done (somewhat complicated unit test) and check waitForCondition() directly?
+4
source share
3 answers

If you inject an ArrayBlockingQueue instance into the constructor of the Check class, then your test can enter the appropriate value in the middle of the test.

You can then run the unit test with a timeout and crash if it does not return within 100 ms or so.

+3
source

Thanks for the nice link! I ran into some similar issues, and maybe this connection is a better way to go than what I did. (I'm also interested to know what other answers appear to this question - this is a good question)

If you don't mind changing (at least temporarily) your actual code (yes, this is not the usual practice of unit testing!), You can do something that I called "Error Injection . "

In my implementation, you create a class that reads properties (or a map) to "make something funny" at a specific unique point. for example your properties can say

 myClass.myMethod.blockingQueueTake = interrupt: myClass.myLongCalculation = throw: java.lang.ArithmeticException(Failed to converge) 

In your code, you add test lines, for example. right in front of your queue.take() , add

 TestSimulator.doCommand("myClass.myMethod.blockingQueueTake"); 

The advantage is that everything happens in real real code, and not in a poppy that can get really hairy. (In my case, SW was older than written / intended for unit testing, so making Mock was very difficult). The downside is that you probably want to delete or comment on the code later. So itโ€™s really not a type of continuous integration of unit test, but rather a one-time really serious debugging. So, I admit, this is far from ideal, but for me he found a bunch of mistakes!

+1
source

You can also use the "test runner" class to run statements in a loop. The loop will trigger statements in try / catch. An exception handler would try to run statements again before the timeout expires. I recently wrote a blog post about this technique. The example is written in groovy, but the concept should be easily adapted for Java.

http://www.greenmoonsoftware.com/2013/08/asynchronous-functional-testing/

0
source

All Articles