Sunday, August 29, 2010

How to accept only strict dates using javascript validations

Well, well, well yes there are a thousand (or even more) date pickers around to help users to choose a date.

But recently in a project, I was faced with a situation where requirement was, to allow user to choose a date via a date picker but also allow them to type in the date if they wish to do so!

Hummm.... I know its a standard requirement. We where using JQuery as our javascript framework and JQuery-UI for the date picker.

Showing the date picker is a child's play all we have to do is:

  • Include the jquery library
  • Include the jquery-ui library and css
  • Invoke the datepicker method on the chosen input field
But allowing user to type in the date is a bigger challenge.
Why? Because they can type in any random value which may not be a valid date.

There are lots of plug-ins available in jquery to stop users from entering chars in date fields etc. Thats easy you see! But the problem is making sure user enters a valid date.

Lets assume that the date format we are using is mm/dd/yyyy.
If the user enters 13/01/2010, clearly its an invalid date since we have only 12 months so far!

But the javascript Date class is very very lenient and it converts the date 13/01/2010 to 01/01/2011 which is a valid date.

And hence for javascript 13/01/2010 is a valid date. But for us, humans its an invalid date!

So how do we validate such invalid inputs and show errors to users?

How do they do it!

The approach I take is as follows. I use two level of defense strategy and heres what I do
  • Step - 1: Use the javascript Date class to find whether user has entered a valid date? If date parsing fails then show and error to the user. This is our first level of defense
  • Step - 2: If we are able to parse the date, then we need to verify if its a valid date. If its not we show an error to the user. This is our second level of defense.
Step - 1 is easy and I am not going to show it.

Step - 2 is done this way

Basically, we first let javascript parse the date entered by user and then we split the date into parts and then verify that
  • The month entered by user is the same as the month held by the parsed date
  • The day entered by user is the same as day held by the parsed date
  • The year entered by the user is the same as the year held by the parsed date
If any of the above conditions fails, we return and error to the user.
If all of the above conditions are true, then user has entered a valid date

The Sample Code:

If you try the above code we get two alerts the first one is Invalid Date. and the second one is Date is valid. and that is exactly what we want!

Mission accomplished!

How to fix "OutOfMemoryError: PermGen space" errors when running Cobertura from Maven2

Recently while working on a project, I was faced with ugly OutOfMemoryError being thrown while running cobertura.

We used Maven2 as the build tool on the project.

I tried various things to fix it but without luck.

A few of those were:

  • Setting the MAVEN_OPTS=-Xms512m -Xmx1024m -XX:MaxPermSize=512m
  • Setting the JVM_OPTS=-Xms512m -Xmx1024m -XX:MaxPermSize=512m
  • Trying the <maxmem> property of cobertura in pom.xml
None of them fixed the issue.

The real problem is surefire plug-in forks a new jvm to run the tests and this jvm does not seem to inherit the memory settings.

So what is the way around is?

We can use the argLine configuration property of the maven-surefire-plugin to bump up the memory.

The above code means:

  • Initial java heap size is 512m
  • Maximum java heap size is 1024m 
  • Maximum size of permanent generation heap is 512m.  
Basically all we are doing is bumping up the memory used by the surefire plugin to run the tests.

All said and done, the real test is in the real world.

After those settings I ran mvn clean cobertura:cobertura and Yes, it worked!

No more OutOfMemoryError!

The sample pom.xml that I used is:

Have fun!

How to mock/stub void static methods using PowerMock

In my previous post we saw how we could mock/stub void instance methods.
In this post we will try our hands at mocking/stubbing another exotic species called void static methods

Yes, I know void static methods should be avoided at all costs!

But sometimes you just cant help it!

So lets look at the code under test

In our example we want to test the upgradeAllCustomers method of the CustomerController.

This method upgrades all customers by invoking a void static method upgradeAll on Customer class. Currently implementation of upgradeAll method of Customer class throws and exception.  

What do we want to test:
  • upgradeAll void static method of Customer class was invoked
  • true is returned after the upgrade
How will we test it - How do they do it!:

The syntax that we had seen in the earlier post will now work anymore

If we notice persist is an instance method on the Customer class (and the above syntax works for instance methods only).

But in this case we want to stub the void static method. How do we do it?

We have to do the following things

  • Use the annotation @RunWith(PowerMockRunner.class) to bootstrap PowerMock itself
  • Use the annotation @PrepareForTest(Customer.class) to be able to stub static methods of Customer class.
  • Stub the void static method using the following lines of code

Notice that the syntax is a bit like record-playback-verify style.

We have to first tell PowerMock to do nothing when a static method is invoked on Customer class.

PowerMock should do nothing on which void static method is specified in the next line by invoking the void static upgradeAll method on the Customer class.

Its effectively recording the fact that, when static void upgradeAll method is invoked on Customer class nothing is to be done!

Before moving, lets see how can we verify that a void static method was actually invoked?

We can easily see that the syntax to verify that a static method was invoked also follows the record-playback-verify pattern.

First we have to inform PowerMock that we are going to verify a static method invocation, and in the next line we actually verify the call to the upgradeAll method.

Enough explanation lets look at the complete test code:

Yes thats how we do it!

For the first time I have to say, and believe me I hate to do so but, I don't like this syntax that much!

But that's just me and hats of to the excellent job that PowerMock and Mockito guys have done so far!

How to mock/stub void methods using PowerMock

Ok, I had though that the previous post would be the last post in the how-to series, but there are so many features in PowerMock that I am tempted to write more about it :)

So, here comes another post on how to mock/stub void methods using PowerMock.

One would think why are void methods so special, that we need a post to explain them?

Well thats because they are void methods. They don't return anything. If you remember, from my earlier post, the syntax of stubbing any method with a non void return type is as follows

In the above example doSomething method of ServiceA instance returns a String.

But imagine what will be the syntax, if doSomething method's return type was void!

May be something like this?

But, if you think for a moment about the above syntax, we would realize that  

methods in java are not very happy to accept void as the argument type!

Effectively, in the above syntax the when method is taking void as one of the argument!

Well this is a problem. This cannot happen!  Hence, we need a special syntax to mock/stub void methods.

So without wasting any more time lets look at the code under test:

In our example we want to test the persistCustomer method of the CustomerController. This method simply calls persist method on the Customer instance passed as argument. Assuming that the persist method of the Customer class returns nothing if everything is fine and throws a RuntimeException if something horribly goes wrong.

We want to write the test case for both these scenarios. So how do we do it?

How will we test it - How do they do it!:

Well, there is always a way with PowerMock!

Our first scenario is to verify that the persistCustomer method returns true if everything goes fine.

PowerMock uses the following syntax to stub the void method to do nothing.


If we read the syntax in pure English it says,

Do nothing when persist method is invoked on customer instance

As simple as that! We are telling the mock customer object to do nothing when persist method is invoked.

Lets look at the test case:


Now the other scenario, we want to make sure that false is returned when an exception is thrown from the persist method of customer instance, but for that to happen we have to stub the persist method of customer to throw an exception.

This is how we do it:

Syntax in English:

Throw RuntimeException when persist method of customer instance is invoked.

Lets look at the test case:

Thats it! Well you see there always is an easy solution with PowerMock

Saturday, July 24, 2010

How to use custom argument matchers using PowerMock

We have come a long way and most likely this will be the last post in the series of how-to do stuff using PowerMock's (Mockito api) - Mocks on Steroid!

Some of the posts in the how-to series are more exotic then the others, but if you want to experience the real power of PowerMock, have a look at testing the UN-testable code.

In the previous post, we saw how we could use various argument matches, in situation when we don't know exactly what argument will be passed. Mockito already has a rich set of matchers but, if you think that is not enough we can write our own Matchers.

Why would you need them? Good question. In most cases the build in matchers are enough, but we might need custom matches when we want to make sure that a certain property of a certain class is set to a certain value.

Well did you understand that above sentence? No? Even I didn't understand that :)

As people say

Picture says a thousand words

my version of the same quote is

Code says everything

So lets look at the code under test.

Look at the argument passed to calculateChargeAmount method.  ServiceA's calculateChargeAmount passes a new instance of Calender to this method.

Of-course by now you already know how to test such a code. But since this post is about custom argument matchers, we will try to write a test for this method using the custom argument matcher.

But how do we write a custom argument matcher?

How will we test it - How do they do it!:

Well, turns out Mockito has a class called ArgumentMatcher. To create a custom matcher we extend the class ArgumentMatcher and override the matches method which returns a boolean.

If the matches method returns
  • true: means that the argument passed matches the criteria
  • false: means that the argument passed does not match the criteria
Along with this we need to use an argument matcher called argThat provided by Mockito. This argument matcher takes in an instance of our custom matcher, which will in-turn decide whether the argument passed matches our criteria.

Lets say in our example, we just want to make sure that the Calendar instance passed to the calculateChargeAmount method represents a date in the future.

This is how we could make use of the custom matcher in this case

Thats it folks! This is how we write custom argument matcher using Mockito.

It has been a pleasure doing this how-to series. I hope you guys have liked reading it as much as I have liked writing about it!

Saturday, July 17, 2010

How to use argument matchers using PowerMock

In my previous post we saw how we could suppress a field. In this post, we will write test case for a more common scenario.

Every time when we stubbed out a method or verified an invocation we have used actual arguments, for e.g.

Or

Notice the argument that we are passing to method2 is "some argument value".
By default PowerMock invokes the equals method on each argument to find whether the arguments match or not.

But what if we want to write the test for the below code

Code Under Test:

Well, looks pretty straight forward class to test. But wait, have a look at the arguments been passed to anotherBusinessProcess method.

The first argument is "Hello World" thats not the problem, the real challenge is the second argument "Another argument + Math.random()". Any one who has worked in Java for a day knows that Math.random() with generate a random number :) and since its "random" we cant determine what is the number till its generated!

So how do we stub the anotherBusinessProcess method on the ServiceB class.

How will we test it - How do they do it!:

Well in such cases where we don't know exactly what argument will be passed to a certain method (which we want to stub) we could use a feature of Mockito called Argument Matchers.

Mockito has a rich set of predefined argument matchers. As the name suggests, argument matchers job is to match the arguments! As in this case we don't know what is the exact argument passed to the anotherBusinessProcess, hence we might say that

"Stub the anotherBusinessProcess method on ServiceB when its invoked with argument Hello World and any string to return Success!"

If you read the statement above carefully, we want to make sure that, the first argument of anotherBusinessProcess method is "Hello World" but the second argument could be "any string". How do we do that? Using Mockito's argument matchers.

The syntax:

Notice that we are using two argument matchers in the above example
  • eq: used to say that the argument passed while invoking the method from the test code is equal to the argumnet passed to the eq method
  • anyString: Means, the argument is any valid string!
NOTE: The difference between the two lines in the above example. In the commented line we are not using the eq argument matcher. The rule is if you are using Mockito argument matcher for one argument you have to, have to, use it for all the other arguments as well.

Hence if you ran the test case using argument matcher for only one argument and passed actual value for the other then Mockito will throw following error

The error message is self explanatory and it give a right solution to the mistake! This is the Mockito's goodness, its extremely intuitive and gives us an awesome error messages!

Moving on, now that we know how to correctly stub anotherBusinessProcess method lets look at the whole test code

anyString does the job for us. But the problem is, it will match any string (well, that is exactly its job! which it does well BTW), what if we want to say that the second argument should startWith "Another argument "?

Mockito has a solution for this as well! Use the startsWith argument matcher.

here is the complete test code.

Mockito has lot of built in argument matchers that we could use, I strongly suggest looking at this link for more examples.

Other argument matchers that could be of interest.

  • isNull - Matches an argument that is null
  • isNotNull - Matches an argument that is not null
  • isA - Matches an argument that is A instance of the given Class
  • endsWith - String that ends with the given value
  • anyCollection - Matches any collection
  • anyMap - Matches any map
  • matches - Matches a regular expression
  • any - Matches any object.

How to fix the OutOfMemoryError when writing tests with PowerMock - Part - 2

In my previous post we had a look at How to fix the OutOfMemoryError when writing tests with PowerMock

Looks like, the method I described in that post does not work on all machine or environments.

In one of the environment whose configuration is:
  • Windows 7 64 Bit
  • 4 GB RAM DDR3
  • Intel Core i7 processor
  • JDK 6 64 Bit  
  • PowerMock 1.3.7  
it seemed to work for some time, but as soon as we wrote a few more tests using PowerMock (Mockito api), the OutOfMemoryError re-appeared.

Now that's annoying, what the hell is wrong now!  Well as I said in the previous post memory leaks are hard to find and fix!

But we need a solution now!  Can't wait till PowerMock 1.4 version is released.  Hence, I was on a mission to fix the issue and get all my tests running by hook or crook!

In the process I found that, running the tests on a 32 bit machine had no problems what so ever!  Surprise, Surprise!

Investigated a little further, found that when tests are run on a machine with 64 bit OS but 32 bit JDK they all pass.  That was the moment of Truth!

These are the steps I followed to fix the OutOfMemoryError:
  • Installed the JDK 6 32 bit on my machine
  • Updated the JAVA_HOME environment variable
  • Added the JDK 6 32 bit bin directory to the PATH environment variable
  • Removed the earlier JDK 6 64 bit bin directory from the PATH environment variable.  
All set!  Ran all the test and bingo!  All pass its a SUCCESS!