Monday, 13 April 2009

Mocking

In this article I will explain a unit testing concept called Mocking. We will also discuss a couple of examples based on EasyMock library.

Unit testing is an integral part of any software development cycle. It is the process using, which a programmer makes sure that the piece of code he/she has developed does what it is supposed to do. In more specific terms a unit test can be defined as the test of a single isolated component that can be done repeatedly. There are various tools available for doing unit testing like Nunit, JUnit etc.

Testing units of code often is a problem because mostly, the components of a software application do not work in isolation but collaborate with other components to get the job done. But in unit testing we don’t want to test the depending objects, but the unit under test. Mocking provides a solution to this problem. All the collaborating objects which are not to be tested can be passed as the ’mock’ objects after setting up their behaviour for the life cycle of the test.
Mock objects are not to be confused with mocks or stubs, which is another library to facilitate the testing of a unit with dependencies.

The basic idea behind Mock Objects is that the dependencies are resolved on the fly with in the test itself. EasyMock provides Mock Objects for interfaces in JUnit tests by generating them on the fly using Java's proxy mechanism.

Let me explain this concept by a very basic example. I have used Easymock for mocking the objects. Consider the following class:
public class Employee 
{
public Employee(String fName, String lName)
{
firstName = fName;
lastName = lName; 
}
private String firstName = null;
private String lastName = null;

public String getFirstName()
{
return firstName;
}


public String getLastName()
{
return lastName;
}

public String displayNameWithDepartment(IDepartment dpt)
{
return firstName+” ”+lastName+” ”+dpt.getName();
}
}

There is an interface IDepartment which is used by our Employee class.
public class IDepartment 
{
public String getName();
public String getHODName();
}

Now let’s consider testing of Employee class. What do we want to test, and how do we go about it. We are mainly interested in the way that our implementation class collaborates with its dependencies. We need to make sure that our class behaves correctly, when interacting with these parameters. We want to make sure that the right methods are called in the right order with the right parameters, but it is not used.
Obviously, in order to test the Employee class’s behaviour we will have to pass it a IDepartment reference but which need not be an actual object.
Lets create an example JUnit test, which shows the EasyMock at work
import static org.easymock.EasyMock.*;
import junit.framework.*;
//other imports omitted

public class EasyMockTest extends TestCase
{
public void testWithMockObjects() throws Exception
{
// strict mock forces us to specify the correct order of method calls
IDepartment dpt = createStrictMock(IDepartment.class); //1

expect(dpt.getName()).andReturn("Development"); // 2

//unexpected method calls after this point will throw exceptions
replay(dpt); //3

Employee emp = new Employee(“Michael”, “Sheen”); //4

assert(emp.displayNameWithDepartment(dpt), “Michael Sheen Development”) //5
//check that the behaviour expected is actually
verify(request); //6
}
//more test methods omitted ...
}

EasyMockTest class tests the behaviour of the displayNameWithDepartment() method in a specific scenario.

Let’s walk through each line of code and find out what it is doing.
1. We ask EasyMock to create dynamic proxy implementing IDepartment, which starts in record mode.
2. Record a method call along with the expected result.
3. replay() call tells EasyMock to stop recording. If we don’t call replay(), a call to dpt.getName() would return null.
4. Create the Employee object that needs to be tested.
5. Call on the mock object returns the set value. If it gets a call it does not expects, it throws an exception.
6. Verifies that only the method calls which were recorded were played. If we make a method call which was not recorded, an ‘Unexpected method call’ error is thrown. Moreover all the method calls which were recorded need to be made.

Note: Methods on the mock object would return the result in the same order in which the expectations were recorded/set on them. If the order does not match our test case is going to fail.
For example if our test case contains following lines of code, it’s going to fail:
expect(dpt.getName()).andReturn("Development"); //Development first
expect(dpt.getName()).andReturn("HR"); //HR second  
replay(dpt);
Employee emp = new Employee("Michael", "Sheen");
assertEquals(emp.displayNameWithDepartment(dpt), "Michael Sheen HR"); //HR first
assertEquals(emp.displayNameWithDepartment(dpt), "Michael Sheen Development");
verify(dpt);

Multiple calls
If a method on a mock object is to be called multiple times, we can use times() method. So if in the above example, I want to set multiple expectations with same arguments, I can use following the following line of code
expect(dpt.getName()).andReturn("Development").times(2);

reset method()
In the above example, the test method has a single replay() and verify() call with single expectation setting and verification phases. Sometimes it is convenient to reuse the same mock object over multiple expectation setting, replay and verification cycles. But the problem is once a mock object has been verified, it cannot record a method call. If we try to do that, an ‘Unexpected method call name’ error is thrown.
reset() method is used to set the mock object back to the expectation setting mode.
For example consider the following two scenarios:
Without reset()
expect(dpt.getName()).andReturn("Development");
replay(dpt);
Employee emp = new Employee("Michael", "Sheen");
assertEquals(emp.displayNameWithDepartment(dpt), " Michael Sheen Development");
verify(dpt);
expect(dpt.getName()).andReturn("Development");  //Error
replay(dpt);
assertEquals(emp.displayNameWithDepartment(dpt), "Michael Sheen Development");
verify(dpt);
With reset()
expect(dpt.getName()).andReturn("Development");
replay(dpt);
Employee emp = new Employee("Michael", "Sheen");
assertEquals(emp.displayNameWithDepartment(dpt), "Michael Sheen Development");
verify(dpt);
reset(dpt); //resetting the mock object back to the recording mode
expect(dpt.getName()).andReturn("Development");
replay(dpt);
assertEquals(emp.displayNameWithDepartment(dpt), "Michael Sheen Development");
verify(dpt);
Nice mocks and Strict mocks
You may have observed we used createStrictMock() to create the Mock objects. There are two other ways to create mock objects.
  • Nice mock
  • Default mock object
All these mocking strategies basically differ in two ways

Optionality
Nice mock allows you to omit expected method calls. If a method is called, but no expectation has been set, then the nice mock simply returns the default value for the type, if the invoked method returns a primitive, or null for an object.
For example, if we change our DepartmentImpl to look like this
public class DepartmentImpl implements IDepartment{
private String name = null;
private String HOD = null;
public String getName() 
{
return name;
}

public String getHODName() 
{
return HOD;
}
}
and change the testWithMockObjects to following
public void testWithMockObjects() throws Exception
{
IDepartment dpt = createNiceMock(IDepartment.class);
replay(dpt);
Employee emp = new Employee(“Michael”, “Sheen”);
assert(emp.displayNameWithDepartment(dpt), “Michael Sheen”)
verify(request);
}
Ordering
Expected invocations on strict mocks need to be specified in the correct order, that is, in the same order that they are executed. In the case of default and nice mocks its not mandatory.

Stubs
Strict mocks are great for defining rigorous tests, but at times applying them can lead to overkill. For example our mock objects contain a bunch of methods, with only some of these of interest. So how can we stop our tests from failing as a result of unexpected behaviour of these "other" methods? This is where Stubs are used.
Consider the code snippet below.
expect(dpt.getName()).andStubReturn("Development"); 
replay(dpt);
Employee emp = new Employee("Michael", "Sheen");
assertEquals(emp.displayNameWithDepartment(dpt), "Michael Sheen A");
...
...
...
...
verify(dpt);
The first line says, if dpt.getName(...) is called one or more times, then each time simply return the String "Development". However, if the method is not called, then don't throw an error. This gives us a lot of flexibility in stubbing out interaction with the mock objects which are irrelevant to the test in consideration.

Summary
Mocking is a powerful technique for helping to obtain high levels of test coverage for our code without worrying much about resolving the associated dependencies. It allows us to specify the behaviour of objects collaborating with our classes under test with a great deal of ease and with a lot more control.
The aim of this article is provide a brief overview of Mocking and overcome the hurdles faced in putting EasyMock to work in their applications.

If you find any problem in the code, or disagree with anything I have mentioned please write to me at ravinder.rawat@gmail.com. You might help me in becoming a more learned person.

Sunday, 29 March 2009

How to safeguard your career in recession

A couple of strategies for making sure that your job is safe in the recession-hit corporate world.

Be a money-spinner
Share client leads or ideas to generate revenue even if that's not part of your responsibilities. The most important resources for any organization are the people who bring/generate business.

Stand out and step up
Make sure people know you, by solving problems and taking on high-profile and critical projects.

Move around in safe zone
Dont keep the company of the people who are not rated very highly by your bosses. Hang out with the people, the boss respects most. The aura of their good reputation may extend to you.

Go beyond your job scope
Look for problem spots that you can help fix and step in whenever extra hands are needed.

Make a sacrifice
Volunteering to take a salary cut during an industrywide downturn can make you look like a hero. This one is a little bit risky but may put you in the good books of your higher management very quickly.

Increase your market value
Enroll for some certification course to add value to your resume. Its really great if you can manage your organization to sponsor otherwise spend out of your pocket. Don't think of it as an expenditure, it is an investment.

Monday, 23 March 2009

KISS, DRY and YAGNI

I am mentioning a few programming philosophies, which seem so obvious yet so difficult to follow. Only after spending a few years in software industry I could realize that the beginners write the complicated code and experts write the simple code and not the vice versa. I believe all these strategies can never be mastered; they can just be bettered.

KISS - Keep It Simple Stupid
I am sure all of us have heard this advice quite often and it still holds its ground. A lot of times we over complicate the solution to make our, otherwise boring, life a little fun. This happens a lot of times in the corporate software development world, where the boredom of routine jobs can be relieved by implementing an intellectual but not required solution. It feels great when we do it but if someone needs to fix, maintain or modify it, I am sure we would be up for a few cuss words. It is quite possible that when even we ourselves go back to our code, we start scratching our heads to figure out what exactly the code is doing. I am sure none of us would want to feel stupid looking at our own code. So just follow the words of the wise - KISS.

DRY - Don’t Repeat Yourself
Try not to repeat your code at a lot of places. Repetition is always a maintenance nightmare. If you need to repeat your code probably its time to refactor your code down to one use. You can refer it from multiple places. If you know your code is going to be used only once, then you are better off with the cut-and-paste approach rather than looking for a more general and thoughtful DRY solution. But if thats not the case, be more thoughtful before you commit the sin of duplication.

YAGNI - You Ain’t Gonna Need It
Don’t build something now because you think you might need it later on. Don’t over plan things. Don’t try to look too far. You might not need to travel that far at all. Try being a minimalist. Don’t try to gold plate things when its not needed. A time might come when the new functionality would not fit in the current code and a redesign would be needed but don’t factor that in too early.

Thursday, 19 March 2009

How to view Hibernate query?

If you want to see the Hibernate generated SQL statements on console, what should you do?

In Hibernate configuration file set as follows:
<session-factory >
...
<property name="show_sql">true</property>
...
</session-factory >

Is little knowledge really harmful?

knowledge is always good, and certainly always better than ignorance. - Sergey Brin (CoFounder, Google)

Method overloading in Java 1.5

This post discusses the behaviour of method overloading in Java 1.5.

Suppose you have a class, which has a method void print(Integer x) and you call print(5) then Autoboxing will come into play and print will be called.

Another case is, if you have a method void print(long x) and you call print(5) then the primitive integer 5 will be widened to long and method print will be called.

Now suppose you have overloaded print method in your class

public class OverLoaded
{
public static void print(Integer i)
{
System.out.println("Integer");
}
public static void print(long l)
{
System.out.println("long")
}
public static void main(String args[])
{
int i = 10;
print(i)
}
}

There can be two possible outputs:
If you think "Autoboxing" will be done, then "Ineger" would be printed.
If you think "Widening" will be done, then "long" would be printed

Since both the method exists, which one will be used? Autoboxing or Widening?
In such situtations compiler uses the following order of priority:
  • Widening
  • Autoboxing
  • Var-args
Next question is what if there is a combination of these operations required.
When there is a combination of the above operations exists, the compiler will perform BoxingAndWidening but it will not perform WideningAndBoxing.

Class WidenNBox
{
static void print(Long x)
{
System.out.println("This is from long");
}
public static void main(String args[])
{
byte b = 10;
print(10);
}
}

In the above case, Compiler needs to widen byte to long first and then it should be boxed to Long which is not allowed.

Now consider this class

Class BoxNWiden
{
static void print(Object x)
{
System.out.println("This is from Object");
}
public static void main(String args[])
{
byte b = 10;
print(10);
}
}

Here compiler would autobox it to Byte first and then it can be widened to an Object.

Monday, 6 October 2008

What is Subprime Lending?

Lehman collpased. HBOS (Halifax Bank Of Scotland) and Merrill Lynch sold out. AIG in doldrums. The recent news of the global financial crisis made me open google and explore about the reasons, which knocked down these titans. As far as I could understand the primary reason for the Lehman's demise was Subprime Lending. Since that term was gibberish to me I did another google search to find out the meaning of that. Here is what I could understand.

Everyone and anyone in this world is in need of extra funds at some point in time. It may be for buying a house, buy an HDTV, a car etc. Suppose, I need to buy a house. Since a house is a pretty big investment, I don't think I can afford to make a down payment of the entire cost. So I look for a financial institution, which can give me a loan as per my financial eligibility or credit score. The credit score is a key factor to determine
  • Whether or not I am eligible for a loan?
  • If I am, then what would be the loan amount?
  • What would be the interest rate on the loan?

Now if my credit score is below than the minimum required by the lending institution then I would be denied a loan. So I have been denied a Prime Lending.

I would look for another institution like Lehman, which is willing to lend to me even with my low credit score. This is called Subprime Lending (Since in this case my house would be mortgaged until I pay back the entire loan amount, it would be called Subprime Mortgage Lending). Of course, I would be charged a higher rate of interest for the loan amount because I am a Subprime Borrower and as per my credit score I have higher risk of defaulting. Besides sub-prime lending rates are also higher because more applications are rejected and marketing costs are higher.

Some subprime lenders are independent but mostly they are affiliates of the mainstream lenders functioning under different names.

Subprime market has made mortgages (and home ownership) available to a segment of the population that otherwise would have been shut out of the market, which is a positive development. The bad part is that some borrowers who are eligible for loans from mainstream lenders end up in the subprime market. They are prime borrowers but they pay subprime prices.

This happens partly because of the difficulties some borrowers face in determining whether or not they qualify in the mainstream market. The main reason some prime borrowers end up paying sub-prime prices is that they are solicited by subprime lenders and go along with the deal pitched to them without ever contacting a mainstream lender. This is referred to as "steering".

I guess thats enough for the definition of Subprime Lending. In case you have any queries, you can always shoot them to ravinder.rawat@gmail.com

 
Technology