Thursday, December 4, 2014

View In-Memory data in HSQLDB

Given that you have setup a test scenario where a set of data has been loaded to the In-Memory HSQL DB, you sometimes need to find out the contents of the DB so you can debug your code. Ideally you would know what you added to the DB but sometimes you need find out what you just added to it and even run queries to see what results are being produced.

We followed this tutorial to set our test scenario for these kind of integration tests.

To access the DB while running the tests, follow the steps below

1. Add following piece of code in your @Before method

org.hsqldb.util.DatabaseManagerSwing.main(new String[] {
  "--url",  "jdbc:hsqldb:mem:testdb", "--noexit"
});


This will kick off a swing application which is fairly well formatted for the purpose.

2. Add a break point using you IDE and run your test in debug mode

3. When the test hits the break point, you should have another window open which will allow you to access your in memory db

When following above steps you find that the window hangs while the program has stopped on the break point, you may need to change your debug configuration.

In IntelliJ, in the 'Debugger' view (where from you can Resume, disable break point etc), find the 'View Breakpoints' icons (to half overlapping red circles) and click it. In the window that appears, Select to suspend only the 'Thread' instead of 'All'.

Wednesday, November 26, 2014

Why do all but first test fail - EasyMock

The answer is probably very obvious most of the time. The first test did one of the following
- changed the state of objects that were used by other tests
- the first test consumed expectations on shared mocked objects
- mock controls were set but not reset at the end of the first test

I ran into this one today. I had all tests passing when running them independently but only the first one passing when running all tests in the file. Having made sure I was resetting the mock controls and the expectations were set correctly, I knew it had to be the first one where the status of objects were changed.

The problem was that my object under test was a singleton class. The first test created the object under test based on mocked arguments in its constructor and the test passed.

However, when the second test was run, despite the fact that I had reset the IMocksControl object in my test, the expectation in my second test were not being  met. You can probably already see what is happening here. The object under test is the same instance (as in the first test - given that its a singleton) and the mocked objects that I passed in during the first test persisted. So when the second test 'expected' things to happen, the expectations were never fulfilled because they were already consumed by the first test. Regardless of whether the object under test was a member variable or a local variable for each test, it did not make any difference.

I fixed the issue by cautiously creating setters with default access so that the second test could supply new set of mocked objects to the object under test. This takes me back to the sameissue that I have never felt comfortable with - exposing for test purpose - but have done it anyway in multiple instances.

Wednesday, November 19, 2014

Testing Thread static method using Powermock

In one of my previous posts, I had talked about mocking static methods using Powermock. Today, I got thrown off a bit when the same technique worked without any issues for any other static methods that I have used so far but when it came to verifying that a 'task' paused for a certain amount of time, I wasn't able to test it and it simply executed the Thread.sleep(xxx) as if no mocking attempt had been made. Although, I wouldn't say I 'solved' the problem, I did find a way to deal with this.

The solution is in fact VERY simply. I extracted the Thread.sleep call to an utility class. I then went ahead an mocked my Utility class and 'expected' the call to sleep method.

public static void sleep(long timeToSleep) throws InterruptedException {
    Thread.sleep(timeToSleep);
}


Instead of catching InterruptedException in the Utility method, the exception is caught in the method that calls this method. This way I can test situation where I throw the exception for the test.

PowerMock.mockStatic(ThreadUtils.class);
ThreadUtils.sleep(600000l);
expectLastCall().once().andThrow(new InterruptedException());

Tuesday, November 11, 2014

Use velocity to generate XML requests

If you are interacting with third party services, there is a chance you will need to write up your request is XML format with details. I will show you how to use Velocity to generate your requests using an XML template.

Get the java library for Velocity Engine and add it to your class path.

Create a .vm file with a template


<MyRequest>
    <name>$name</name>
    <value>$double.doubleValue()</value>
    <action>$action</action>
</MyRequest>



Java Code

VelocityEngine engine = new VelocityEngine();
engine.init();

VelocityContext context = new VelocityContext();
context.put("name", "GET");
context.put("action", "someAction");
context.put("double", new Double(4));

Template template = engine.getTemplate(requestTemplateFile);

StringWriter writer = new StringWriter();
template.merge(context, writer);

System.out.println(writer.toString());

Your resulting xml will be like below


<MyRequest>
    <name>GET</name>
    <value>4.0</value>
    <action>someAction</action>
</MyRequest>

  

Wednesday, November 5, 2014

How do delete remembered selected item from browser

When you use a website regularly which requires searches, you will soon end up with whole lot of words that accumulates and come up as suggestions. This might be a good thing at times and you don't have to type the whole work again.

However, imagine typing a wrong email address on your favorite website, pressing the Return (Enter) key and finding out that it always show up next time you want to use the website. Or, at times you just don't want to see the suggestion without having the delete all the browser caches.

All you need to do is
1. Bring up the suggestions by either starting to type the work or by double clicking on the input field. Do not click it
2. Scroll using the keyboard (down arrow) or using the mouse by simply hovering over it.
3. Press Shift+Delete key.


Decompiler in IntellJ

JetBrains  released IntelliJ 14 just yesterday. As mentioned in the release notes, IntelliJ now has built in decompiler. It makes it really easy to view the source code for external libraries you are using. Although the variable names read var1, var2...varN, it is still an excellent experience.

Thursday, October 30, 2014

Monitoring External Scheduled Jobs Using Jenkins

Recently we had a requirement to create a dashboard so we could monitor our scheduled jobs that were important for the business. The jobs ran on different server boxes. Every now and then when we had issues with a any job, we needed to get access to the system and dig the log files. Worst of all was that we would only know about a problem with the job only when someone reported it. We wanted to build a dashboard so were on top of the jobs' status and fix issues ASAP.  Some research from our team suggested that Jenkins could help us with that.

We got an instance of Jenkins running very quickly and started playing around it. Below is what we did to get a dashboard going.

Jenkins as a Monitoring System

Firstly, we created 'Monitor an External Job' item in Jenkins. Let's call it "JobMonitor1". The configuration required for such an item in Jenkins is very minimal. All you need to do is configure how long do you want the builds (job running records) for.

Now that we had a job - we needed to get the actual JOBs that are running in a different environments to let Jenkins know that it has run. This is where the Monitoring External Jobs plugin came very handy. The plugin page shows how to use this plugin. In summary, we installed the plugin in our Jenkins instance and then got our JOB to send feedback to Jenkins. If we currently ran our job in this manner - bash runMyBash.sh, we updated it to run as follows -

java -jar /path/to/jenkins-core-*.jar "JobMonitor1" bash runMyBash.sh.

We needed to make sure some of the required jar files were available in the classpath. To let the system know which Jenkins instance to post the results to, we needed to set JENKINS_HOME in the system by running the command below.

EXPORT JENKINS_HOME= /path/to/jenkins (for Linux Systems)

SET JENKINS_HOME= /path/to/jenkins (for Windows)


When our script (runMyBash.sh) completed, it sent the details of the jobs to "JobMonitor1" and we could then monitor it in Jenkins. The downside of this approach was that we could not tell from viewing Jenkins whether the job was running. Jenkins is only notified after the process completes. We do however know how long it took for the job to complete.

Monitoring the Monitor

Now that we had the visibility of whether the last ran, passed or failed, to make it a bit more real-time, we needed to know whether the JOB ran when it was expected to run. For example, if a job is expected to run every hour, did it run every hour?

This is where it gets little dirty. We decided to create another item (e.g. "SecondLevelMonitorJob") in Jenkins that would monitor the  Jobs that  were getting notified by the remote system. So we created new 'Freestyle Project' item in Jenkins that would monitor the other job. But how exactly do you monitor it? This is where we found another plugin - check_jenkins_cron. This is simply a script that runs to see if a job that you specified ran in the time you specified.

We wrote a wrapper around this plugin to make the build fail or pass depending on what the plugin returned. So the "SecondLevelMonitorJob" would run our wrapper script. We specified in this JOB how often we expected the job to run. We made  "SecondLevelMonitorJob" run every 15 minutes to monitor a job that is expected to run every 6 hour. This way we picked up the fact that something is wrong with the job ASAP.

Dashboard

And the final piece - the Dashboard. After a lot of investigation on appropriate "Views" for Jenkins, we settled for Wall Display plugin. Some of the others we looked into either couldn't display the 'External Monitor Jobs' or the the view wasn't what we were looking for. Wall Display served our purpose very well - Big Green vs Big Red to indicate how our jobs were doing.



Tuesday, October 21, 2014

Testing Old/Legacy Code using Powermock

I am sharing some of my finding/learning during my attempts to write tests for some codes that were not quite designed for writing tests

Breaking the dependency

You will probably find plenty of dependencies that will be very difficult to satisfy from your unit test which can be very demotivating to write tests. This link has a good description on how to break such dependencies in legacy code. Is shows how to separate the DB connection layer from the service to help making the class more testable. One approach I have taken when you have codes like this  ServiceFactory.getService("MyService"), in the method you are testing is to pass in MyService to the class file via its constructor so that you can easily pass in a mocked MyService.

Static method calls

Static method calls that are in the method that you are trying to test can be very annoying. Use PowerMock's mockStatic method to mock such calls. This link has a good explanation of how to do this. In summary, declare the class with the static method at the class level with PrepareForTest annotation e.g. @PrepareForTest({JOptionPane.class, MyFactory.class}) and do the rest in your test method. An example is below -

        PowerMock.mockStatic(JOptionPane.class);
        JOptionPane.showMessageDialog((Component) anyObject(), (String) anyObject(), (String) anyObject(), anyInt());
        expectLastCall().once();
        PowerMock.replay(JOptionPane.class);



Capturing arguments

 At times capturing the argument and verifying the content is the only thing you can test and you can do this the following way.

        Capture capturedArgument = new Capture();
        mySerivce.updateMyListIdDb(and(capture(capturedArgument), isA(List.class)));

       
        //replay
        //test method call
        assertEquals(capturedArgument.getValue().size(), 1);
        MyListClass listClass = (MyListClass) capturedArgument.getValue().get(0);
        assertEquals(listClass.getValue(), "myExpectedValue");


A cleaner way to do this with latest easy mock is as below:
        Capture<List> capturedArgument = new Capture<List>();
        mySerivce.updateMyListIdDb(capture(capturedArgument)));

        //replay
        //test method call
        List myList = capturedArgument.getValue();
        /assert

VerifyError

I ran into this error when a static method was invoked on a class which in turn has a static field  which needed to be loaded first. I am not exactly sure why this would happen.

java.lang.VerifyError: (class: javax/swing/plaf/metal/MetalLookAndFeel, method: getLayoutStyle signature: ()Ljavax/swing/LayoutStyle;) Wrong return type in function
    at javax.swing.UIManager.setLookAndFeel(UIManager.java:560)
    at javax.swing.UIManager.initializeDefaultLAF(UIManager.java:1329)


Decorate your test class with @PowerMockIgnore("javax.swing.*")

This defers the loading of class or classes provided in the annotation to the systems class loader. If there are multiple classess you would like to defer then try this - @PowerMockIgnore({"javax.swing.JCheckBox", "com.apple.laf.*"})