Unit testing Java exception handling using JMockIt

How do you test that a method caught an exception? What if that catch did not have a side effect, it just logged output, or simply swallowed the exception?

Context
We have a method in a class that was written with a try catch and we need to unit test it. There are many ways this task can occur, such as the need to test legacy code or the need to write a test before a refactoring of such code.

We won’t go into the anti-pattern aspects or what constitutes proper handling of an exception here.

Error hiding is an anti-pattern in computer programming. Due to the pervasive use of checked-exceptions in Java, we must always address what to do with exceptions. Error hiding is when a catch clause does not property handle an exception.
 

In a catch block there are three common ways of handling an exception:

try{
   ... stuff ...
}catch(X){
   // 1. do something here
   // 2. maybe throw X or something else
   // 3. skip the above and do nothing
}

How are these tested?

When the method reacts by throwing an exception we can test using the standard JUnit @Test(expected=SomeException.class), or for fine-grained verification, the test itself has a try catch block where we can assert the exception details.

If a method does nothing in the catch block, which is also called “swallowing” the exception, should it even be a test issue? Yes. The method is just tested normally. One of the tests must force the exception, of course. We do this since in future the method may be changed to handle the exception differently.

It gets more interesting when the catch block has ‘behavior’. This behavior has side effects. If these side effects are only local to the method, such as setting a flag false, then normal testing is adequate. If this behavior has side effects at the class or with collaborator objects, then this requires more complex testing.

It can get murky with this kind of testing. What is important is that one does not test the implementation (but sometimes that is crucial), only the interactions and requirements of the target “Unit” under test. What constitutes a “unit” is very important.

“Typically, a unit of behavior is embodied in a single class, but it’s also fine to consider a whole set of strongly-related classes as a single unit for the purposes of unit testing (as is usually the case when we have a central public class with one or more helper classes, possibly package-private); in general, individual methods should not be regarded as separate units on their own.” — Rogerio in JMockit Tutorial

.

Example
The method being tested invokes a method on a collaborating object and that object throws an exception. In the catch block, the exception is logged using the logging utility collaborator . Though not part of an explicit API, that logging may be critical to the use of a system. For example, an enterprise log monitoring system expects this logging for support or security concerns. A simple class Shop is shown in figure 1,

Figure 1, the class to test

public class Shop {
    private ShoppingSvc svc;
    
    /**
     * Get product name.
     * @param id the unique product id
     * @return the product name
     */
    public String getProduct(int id){
        String name = "";
        try {
            name = svc.getProductName(id);
        } catch (Exception e) {
            Logger.getAnonymousLogger()
			.log(Level.SEVERE, 
			"{result:\"failure\",id:\""+ id + "\"}");
        }
        
        return name;
    }
    
}

JMockit supports two type of testing: behavior and state-based.
Using the state based approach we create a mock for the getProductName(String) method of the collaborating (or dependent) class, ShoppingSvc. With JMockit this is easily done as an inline MockUp object with the target method mocked to throw an exception.

Listing 2, mocking

new MockUp<ShoppingSvc>() {
    @Mock
    public String getProductName(int id) throws IOException{
		throw new IOException("Forced exception for testing");
    }
};

JMockit’s behavior based support is then used to test the catch clause handling. As in other mocking frameworks, a record-replay-verify phases are used. Since the side effect of the exception handler here is the use of the logging dependency and we are not testing the logger, we ‘behaviorally’ mock the Logger class.

We can do this in the test method signature, @Mocked final Logger mockLogger. This mocks every method in the logger class. Then we set an expectation on the log method being used in the exception handler, then verify the method was actually invoked.

The full test class is shown in figure 3 below and the sample code is in a repo on GitHub:https://github.com/josefbetancourt/examples-jmockit-exceptions.

An alternative to using both state and behavior mocking is to just specify the exception throwing with the expectations. The article “Mocking exception using JMockit” shows how to do this. Of course, the JMockit Tutorial has all the details.

Listing 3, the full test class

@RunWith(JMockit.class)
public class ShopTest{
    /**
     * 
     * @param mockLogger Logger object that will be behaviorally mocked.
     */
    @Test
    public void shouldLogAtLevelSevere(@Mocked final Logger mockLogger)
    {
        /**
         * state-based mock of collaborator ShoppingSvc
         */
        new MockUp<ShoppingSvc>() {
            @Mock
            public String getProductName(int id) throws IOException{
                throw new IOException("Forced exception for testing");
            }
            
        };
        
        // the SUT  
        final Shop shop = new Shop();

        // what we expect to be invoked
        new Expectations() {{
            mockLogger.log(Level.SEVERE,anyString); 
        }};
        
        shop.getProduct(123); // actual invocation
        
        // verify that we did invoke the expected method of collaborator
        new Verifications(){{
            mockLogger.log(Level.SEVERE, anyString);  // we logged at level SEVERE
        }};
    }
}

Alternatives?
Just write better code so that you don’t need unit tests? This is mentioned in Functional Tests over Unit Tests

Test using a scripting language like Groovy? See Short on Time? Switch to Groovy for Unit Testing

Software
- JUnit: 4.12
- JMockit: 1.18
- JDK: 1.8
- Eclipse: Mars
- Maven: 3

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Continuous Integration (CI) misconception

In some online resources the term Continuous Integration (CI) is always used in the broadest sense to mean that on some schedule or event the outputs of every ongoing project or separate teams are obtained, put together somehow, and then a test system is updated so that various tests can be invoked. No wonder some test and management professionals are wary of the concept.

The problem here is the “other” usage. More correctly CI can even be applied to one team on one project. One distinguishing feature of CI is that there are multiple developers*. Thus, as these developers complete various tasks and commit or push to a shared repository, a build and deploy process is run to create testable systems.

The term “integration” in CI is applicable to more inclusive senses, or a fuzzy continuum, from one project and one team to combinations of these. Thus, some processes are CI to a certain degree, or worse very CI anti-pattern to a certain degree.

In the modern CI best practices, CI is done via various build and deployment servers that automate some or all of the pipeline. In the past at some companies, the designated build person was doing manual Continuous Integration.

Sure, in CI there will be episodes of actual integration with other current projects, teams, or externally generated artifacts. If this is automated, then we have full CI.

* Even a single developer who uses various branching strategies on one code base may use CI practices.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Ant hooks using Groovy via XML transform

This time the Ant Hook scripts using Groovy is implemented by transforming the target Ant build script. (old post in draft status)

In the post, Ant Hooks using Groovy Script via Scriptdef, we used the Ant BuildListener interface to add a hooks feature that invokes a Groovy script mapped to build events. Then in the last post Ant hooks using Groovy, continued we added the ability to skip a target execution.

The problem with the former implementations is that the target Ant script must be modified to take advantage of hooks. Using XMLTask, we can modify the ant script directly. The InsertHooks.groovy script reads the hooks.inix file and transforms the build.xml to build-hooked.xml. The build-hooked.xml file will have an Ant build listener set to the Hook.groovy script.

The scripts are not general purpose, of course. Just a proof of concept thing.

Approach

hooks.inix:

[>hook/root/compile?when=after,skip=false]
	println " hook: root,{target=${event.target.name},when=post,event=$event}"
[<]

[>hook/demo1/deploy?when=before,skip=true]
	println "  hook: {project=${event.project.name},target=${event.target.name},when=pre,event=$event}"
[<]

[>hook/demo1/compile?when=before,skip=false]
	println "  hook: {project=${event.project.name},target=${event.target.name},when=pre,event=$event}"
[<]

[>fragment]
	<path id="libs">    
		<fileset dir="lib">
            <include 
                name="groovy-all-2.2.1.jar" />
        </fileset> 
    	
    	<pathelement location="src/main/groovy"/>
	</path>    
     
    <!-- Groovy library -->
    <taskdef name="groovy"
       classname="org.codehaus.groovy.ant.Groovy"
       classpathref="libs"/> 
    
    <!-- sets a BuildListener to the project -->
    <scriptdef name="set-listener" 
        language="Groovy"
        classpathref="libs" 
        src="src/main/groovy/com/octodecillion/util/ant/Hook.groovy"> 
    	<attribute name="path"/>
    </scriptdef>
     
    <!-- install the listener -->
    <set-listener path="hooks.inix"/>   
     
[<fragment]

InsertHooks.groovy

package com.octodecillion.util.ant

import static com.octodecillion.util.inix.Inix.EventType.END

import com.octodecillion.util.inix.Inix

import org.apache.tools.ant.*

import static groovy.io.FileType.FILES

/**
 * Insert the XML into Ant script to enable hooks.
 *   
 * @author josef betancourt
 */
class InsertHooks{

	def ant
	def DEBUG = false
	static final String srcFilePath='build.xml'
	static final String destFilePath="build-hooked.xml"
	static final String INIXFILE = 'hooks.inix'	
	static final String XMLTASK = 'com.oopsconsultancy.xmltask.ant.XmlTask'
	
	static main(args){
		new InsertHooks().execute()
	}
	
	/** An Ant task entry point */
	public void execute() throws BuildException{
		def ant = new AntBuilder()
		
		try {
			
			def fragment = loadFragment(INIXFILE)
			if(!fragment){
				throw new BuildException("'fragment' from $INIXFILE is invalid")
			}		
			
			def engine = new groovy.text.SimpleTemplateEngine()
			def template = engine.createTemplate(fragment)			 
			def xml = template.make([hookFilePath:INIXFILE])
			  
			ant.path(id: "path") {
				fileset(dir: 'lib') {
				   include(name: "**/xml*.jar")
				}
			}
	 
			ant.taskdef(name:'xmltask',classname:
				XMLTASK,
				classpathref: 'path')
			 
			def xpath = '(//target)[1]' 
			ant.xmltask(source:srcFilePath,dest:destFilePath, 
				expandEntityReferences:false,report:false){
				insert(position:"before",path:xpath,xml:xml)				 
			}
				 
			new File(destFilePath).eachLine{
				println it
			}
			
		} catch (Exception e) {
			e.printStackTrace()
			throw new BuildException(e.getMessage(), e)
		}
	}
	
	def loadFragment(String path){
		def text = ''
		def inix = new Inix(path)
		def theEvent = inix.next()
		 
		while(theEvent && theEvent != Inix.EventType.END ){
			Inix.Event event = inix.getEvent()

			if(event.isSection("fragment")){
				text = event.text
				break
			}
			
			theEvent = inix.next()
		}
		
		return text
	}	
	
}

// end Script

Hook.groovy

package com.octodecillion.util.ant

import groovy.transform.TypeChecked;
import groovy.transform.TypeCheckingMode;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern

import com.octodecillion.util.inix.Inix

import org.apache.tools.ant.BuildEvent
import org.apache.tools.ant.BuildException
import org.apache.tools.ant.Project
import org.apache.tools.ant.SubBuildListener;

import static groovy.io.FileType.FILES

// wire in the listener
def path = binding.attributes.get('path')
if(!path){
	throw new BuildException("'path' to hook inix not set")
}

def listener = new HookListener(project,path)
listener.project = project
project.addBuildListener(listener)

// end wiring

/**
 * Ant build listener that invokes groovy hook scripts.
 *  
 * @author josef betancourt
 *
 */
//@TypeChecked
class HookListener implements SubBuildListener {
	Project project
	boolean DEBUG = false
	
	/**                          */
    def HookListener(Project project, String path){
		this.project = project
		loadInix(path)				
    }    
    
	/** load scripts in inix file */
	def loadInix(String path){
		debugln("load inix")
		def inix = new Inix()
		inix.reader = new BufferedReader(
			new FileReader(new File(path)))
		 
		def theEvent = inix.next()
		def found = false
		 
		while(theEvent && theEvent != Inix.EventType.END ){
			def event = inix.getEvent()

			if(isHook(event)){
				found = true
				def key = [event.path[2],((String)(event.params['when'])).
					toUpperCase()].join('/')
					
				String txt = event.text
				String skString = event.params['skip']
				boolean sk = (skString.compareTo('true')==0 ? true : false)
				debugln "key=$key, ${event.params['skip']}, skip=$sk"
					
				def node = new HookNode(txt, sk)
			
				def prj = event.path[1]				
				if(!hooks[prj]){
					hooks[prj] = [:]
				}	
				
				hooks[prj].put(key,node);			
			}
			
			theEvent = inix.next()
		}
		
		dumpHooks()		
		
	}

    /** invoked by Ant build */
	@Override
    public void targetStarted(BuildEvent event) {
		die("targetStarted invoked with null event", !event)
		invokeTargetHook(event, When.BEFORE)
    }
    
	/** invoked by Ant build */
    @Override
    public void targetFinished(BuildEvent event) {
		die("targetFinished invoked with null event", !event)
		invokeTargetHook(event, When.AFTER)
    }

    /** Invoke the target's hook script */
    def invokeTargetHook(BuildEvent event, When when){
        def b = new Binding()
        b.setProperty("event",event)
		b.setProperty("hook",this)
		
        def shell = new GroovyShell(b)
		
		def hookName = "${event.target.name}/$when"
		def pHook = hooks[event.project.name][hookName]
		def rHook = hooks['root'][hookName]	
		debugln("invokeTargetHook: $hookName\npHook:  $pHook\nrHook:  $rHook")
			
		boolean skipSet = false
		
		if(pHook){
			skipSet = pHook.skip	
			debugln("skipSet=$skipSet")
			shell.evaluate(pHook.text)
			
			if(!override && rHook){
				skipSet = skipSet ? skipSet : rHook.skip
				shell.evaluate(rHook.text)
			}			
			
		}else if(rHook){
			skipSet = rHook.skip			
			shell.evaluate(rHook.text)		
		}
		
		if( skipSet && (pHook || rHook) && (when == When.BEFORE) ){
			createSkipforTarget(event)
		}		
    } 

	/**   */
	private createSkipforTarget(BuildEvent event) {
		debugln "setting skip: ${event.target.name}_skipTarget"
		event.project.setProperty("${event.target.name}_skipTarget", "true")
		event.target.setUnless("${event.target.name}_skipTarget")
	}
	
	/** throw exception if flg is true */
	private die(Object msgObject, boolean flg){
		if(flg){
			throw new IllegalArgumentException(String.valueOf(msgObject))			
		}		
	}	
	
	@TypeChecked(TypeCheckingMode.SKIP)
	private isHook(ev){		
		ev.path && ev.path[0] == 'hook'		
	}
    
	private dumpHooks() {
		if(!DEBUG){
			return			
		}
		
		hooks.each{
			it.each{ node ->
				debugln(node)
			}
		}		
	}
	
	private debugln(Object msg){
		if(DEBUG){
			println(msg)
		}
	}
	
	String TARGETHOOK = "target"
	def override = true;
	
	enum When{
		BEFORE('before'),AFTER('after')
		String name
		
		When(s) {this.name = s}
	}
	
	private class HookNode {
		String text
		boolean skip
		public HookNode(String text, boolean skip){
			this.text = text
			this.skip = skip
		}
		
		def String toString() {return "s:$skip"};
	}
	
	Map<String, Map<String,HookNode>> hooks = [:]
	
    //@formatter:off
    @Override
    public void subBuildFinished(BuildEvent event) {}
    @Override
    public void subBuildStarted(BuildEvent event) {}
    @Override
    public void buildFinished(BuildEvent event) {}
    @Override
    public void buildStarted(BuildEvent event) {}
    @Override
    public void messageLogged(BuildEvent event) {}
    @Override
    public void taskFinished(BuildEvent event) {}
    @Override
    public void taskStarted(BuildEvent event) {}
	//@formatter:on
} // end class HookListener

// end Script

Further reading

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Adaptive log level based on error context

The other day I was thinking about my companies’ application logging system, and wondered why we don’t increase the log output when there is a problem? I mean doing this automatically.

Problem
If a method in a class is logging at the ERROR level, and an exception occurs, the log output is useful at that level, it contains a stack-trace, for example. However, there are more levels below ERROR that contain much more info that could be useful in maintaining the system. Levels are used to control the logging output in logging systems. For example, in java.util.logging there are seven default levels: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST.

Solution
One way of getting at this useful information is by the class with the detected exception setting the log level in that problem method or function to a more verbose level. The algorithm would probably be similar to the Circuit Breaker design pattern.

Like “First Failure Data Capture” this approach could be called Nth Failure Data Capture.

Issues
Of course, while this may be easy to do this programmatically, in practice, this is not simple approach. Many questions remain: performance; resources; is one error occurrence enough to trigger a change; are all threads effected; which target level; how much logging, how to reset the level, and so forth.

Funny, I’m sure this is not a new idea. A quick search makes it look like it is not a well-known approach.

Alternatives

  • Record everything instead of logging just some things. This is possible with some systems, for example Chronon?

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

How to easily siphon water from pool cover

Time to open up the pool. This time I’ll use my brain and figure out how to do this better.

Yucky Method
The cheapest way to do this is by getting a short length of hose, putting one end in the pool, the other in your mouth and getting the air out. Once that is done, if you take the end and lower it below the other end in the pool, the laws of physics take over, and planet will try to make the two ends of the hose have the same water pressure. Thus, the water starts draining out.

But, that is yucky. You have to really put your arms in that dirty water, and you may get some of it when you suck out the air. I see little wiggly worms in there.

My Method
Get one of those large plastic water jugs. Like the ones used in water dispensers.

pool-siphon

  1. Put a hole in the cap so that you can push the hose thru.
  2. Fill the jug with water.
  3. Put the cover back on the jug.
  4. Now one end of the hose is in the jug. Take the other end and stick it in the pool.
  5. Carefully, move the jug closer to the pool and upend the jug.
  6. Water will start draining from the jug into the pool. This will remove the air in the hose!
  7. Pull the hose in the jug so that it is bottom of jug. This will allow you to flip the jug over again and prevent air to get into the hose.
  8. Bring the jug below the height of the other end in the water.
  9. Now when you flip the jug over, the pool water will be draining out.

Writing down the steps makes it seem complicated. All your trying to do is remove the air from the old hose your using to siphon out the water. It’s just like that motor gas siphoning technique.

An even better better way?
This video shows an alternative method. I didn’t try this, but the video shows it working. If you have a long enough hose, you can connect put that hose in the pool. Turn on the water. When all the bubbles have stopped coming from the end in the pool, turn off the faucet. Disconnect end of the hose at the faucet side. If the height of the pool is higher than the final end of the hose you should start getting water draining from the pool.

Or you can buy a pump. I once bought a cheap pump and it didn’t last one day of use.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Do tablets have a black screen of death problem?

Just happened to my tablet, a Samsung Tab Pro 10.1. If you search online for this you find many discussions and pleas for help. Does this happen to other brands of laptops?

BTW, there is also a White Screen of Death associated with iPod, iPad, or iPhone.

On restart, the screen would not show. Sound is ok, buttons seem functional. A restart or reset using button combinations did not fix this.

The Fix
Luckily I found some instructions on how to fix this. Remove the back cover, disconnect the LCD cable, wait for a few minutes, then reconnect.

Note: Now my WI-FI level is very low. Yikes! I took it apart to see if there is some kind of antenna connection to the case or cover. Don’t see anything. waaaaaa. (;゚︵゚;)

Update: June 18, 2015 – Changed the channel my wi-fi router was using. Fixed! But, now if I hold the tablet at edge, get low WI-FI level. Arrrrr. >:(

 

One person wrote Galaxy Tablet Reboot Trick. Too bad I did not try that first.

Notes

  1. Doing this may void your warranty.
  2. Don’t use a metal device to pry the back cover off. Get a plastic prying device that are sold in kits for this kind of thing. Or use a guitar pick.
  3. Getting the cover off takes a lot of careful prying.
  4. Some people recommend you disconnect the battery connector before you disconnect the LCD connector.
  5. Getting the cover back on is just as hard. I still don’t have it seating well.

Background
Note that all (?) electronic components that have multiple connected parts will have issues. When I worked with metrology components or Electrochemical control devices, sometimes the only thing that would fix them was to disconnect and reconnect some device or subsystem, wait a while, then turn the unit back on. I just read that this is one technique to ‘fix’ ECU units on some automobiles.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

maven-tomcat7-plugin not extracting the war file

The Apache Tomcat Maven Plugin has a great feature: it can create a runnable jar file with an embedded Tomcat server.

I tried this on a simple ‘Hello world!’ webapp to see if this works. It didn’t. When you run the jar: java -jar target\hello.jar, it would fail saying that the hello.war could not be found.

Of course I tried many different configurations and Maven POM file changes. Web searches did not point to an issue. Finally at the end I found something. There is a bug in the plug-in version 2.2. Errrrr.

Anyway, here is a suggestion to get around it. Made the changes, it works.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Why not store numbers as diff of previous number?

This morning had a thought. We store numbers in a fixed sized memory space. So if we use four bytes to store numbers we would need eight bytes to store the numbers 5 and 6. But, what if we store 5 in four bytes and then 6 in two bit, as a delta? The bits can indicate +1, 0, -1., here an increment of the 5 by one. Larger increments would use more bits of course. Thus, we naturally get compression.

Subject areas: mobile computing, Internet of Things.

True, this wouldn’t work as a ‘live’ memory storage, the I/O would be complex. Or would it? In constrained devices such as Wearable Computing, for example, a smart watch, or in an Internet Of Things remote device, memory limitations may require compressed storage.

As usual, this is not a new idea. It is related to “Delta Encoding” or “Data differencing”. An interesting article on how delta coding could be used for compression is “Effective compression using frame-of-reference and delta coding”.

I have not seen this delta encoding memory approach mentioned anywhere yet.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Got my Raspberry PI’s wifi and keyboard configured

Hit a bump getting the wifi dongle working. So I started following some instructions. Now that gave me another problem, the keyboard was not mapped correctly. When I typed a double quote I got an ‘@’ symbol. Turns out that the locale and keyboard were not set correctly for North America.

To fix the locales: Remapping the Keyboard
To fix the keyboard layout this video gave the simplest approach: Raspberry Pi – Change keyboard layout to US from default British layout
To fix the wifi problem this page was the solution: How to Set Up the Ralink RT5370 WiFi Dongle on Raspian

Test … my third monitor is now showing a page on the web. Cool. The Raspberry Pi 2 (Model B) is pretty fast.

Updates
May 24, 2015: I was having issues where the device would lock with blank screen and not respond to mouse or keyboard. Looks like the issue is the WI-FI dongle and the USB subsystem in this Linux. The log shows USB errors. Nothing seemed to fix this. The usual suggestion is to use an external powered USB. On a chance I updated the Linux OS and now the system is working fine. I can leave the PI on.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

JSON as a configuration language

JSON as a configuration data file is already a given. I wrote about this before. Google has now made this even more powerful by open sourcing Jsonnet, a “mini-language”, domain specific language (DSL) on this data format. Jsonnet it supports inline comments. Nice!

If your scratching your head and wondering why, JSON is JavaScript, then you don’t understand what JSON is. JSON is a ‘data-interchange format’. It happens to be based on a subset of the JavaScript language, but it could have been in Python, Groovy, or any other scripting language. Undoubtedly, JavaScript’s ubiquitous use on the web is why JSON was optimal.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.