Tuesday 17 June 2014

EasyMock : Simple Tutorial

EasyMock provides an easy way to create Mock Objects for interfaces and classes generating them on the fly. It is a mock framework which can easily be used in conjunction with JUnit. It is a perfect fit for Test-Driven development.

In this post, we will see how EasyMock can be used to easily test our Java application. EasyMock is helpful in situations wherein you want to mock some of the objects in an application for testing purposes. Service layer classes which often talk to external database/server can easily be mocked. One can easily define the behavior which is expected in response to a certain event. 

I have made use of PowerMock to invoke methods in an object. We need EasyMock, Objenesis and Cglib libraries added to the classpath.You can find the complete source code here.

This is how you create a mock object and specify what is to be returned in response to a certain expected event.

Retailer retailer = EasyMock.createMock(Retailer.class);

EasyMock.expect(retailer.getPriceForProduct("101")).andReturn(220);

The createMock() creates a mock retailer object. Whenever a call is made to getPriceForProduct() with "101" as the productId argument the returned value will be 220 as set by EasyMock.

Also, we need to activate our mock object before making its use using replay() method.This replay() is to be done after specifying all the expectations and returns.

EasyMock.replay(retailer);

Here is an Example. We have a customer class which has retailer object as its member.
package com.nirman.easymock;

public class Customer {

 String name;
 Retailer retailer;

 public int getProductPrice(String productId) throws Exception{
  int price = retailer.getPriceForProduct(productId);
  return price;
 }
 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Retailer getRetailer() {
  return retailer;
 }

 public void setRetailer(Retailer retailer) {
  this.retailer = retailer;
 }

}

This is the Retailer class.
package com.nirman.easymock;

public class Retailer {

 private int taxes_in_percent = 10;

 public int getPriceForProduct(String productId) throws Exception {
  int price;
  if (productId.equals("101")) {
   price = getPrice(100);
  } else if (productId.equals("102")) {
   price = getPrice(200);
  } else if (productId.equals("103")) {
   price = getPrice(300);
  } else {
   price = 0;
  }
  return price;
 }

 private int getPrice(int basePrice) {
  int finalPrice = basePrice + ((basePrice * getTaxRate()) / 100);
  return finalPrice;
 }

 public int getTaxRate() {
  return taxes_in_percent;
 }
}

There is a method getPriceForProduct(String productId) which takes productId and returns its price after adding the taxes that are applicable. We will mock this method using EasyMock. 

This is my JUnit -
package com.nirman.easymock;

import org.easymock.EasyMock;
import org.junit.Test;
import org.powermock.reflect.Whitebox;
import static org.junit.Assert.*;

public class TestRetailer {

 // Without any mocks
 @Test
 public void testGetPriceForProduct() throws Exception {
  Customer customer = new Customer();
  Retailer retailer = new Retailer();
  customer.setRetailer(retailer);
  int actual = 0;

  String productId = "101";
  actual = Whitebox. invokeMethod(customer, "getProductPrice",
    productId);

  int expected = 110;
  assertEquals(expected, actual);
 }

 // Mocked the getPriceForProduct() in retailer
 @Test
 public void testGetPriceForProductEasyMock() throws Exception {
  Customer customer = new Customer();
  Retailer retailer = EasyMock.createMock(Retailer.class);
  customer.setRetailer(retailer);
  EasyMock.expect(retailer.getPriceForProduct("101")).andReturn(220);
  EasyMock.replay(retailer);

  int actual = 0;

  String productId = "101";
  actual = Whitebox. invokeMethod(customer, "getProductPrice",
    productId);

  int expected = 220;
  assertEquals(expected, actual);
 }

 // Assertion Error. As the mock is not activated, actual returned is 0;
 @Test
 public void testGetPriceForProductAssertionError() throws Exception {
  Customer customer = new Customer();
  Retailer retailer = EasyMock.createMock(Retailer.class);
  customer.setRetailer(retailer);
  EasyMock.expect(retailer.getPriceForProduct("401")).andReturn(220);
  int actual = 0;

  String productId = "401";
  actual = Whitebox. invokeMethod(customer, "getProductPrice",
    productId);
  int expected = 220;
  assertEquals(expected, actual);
 }

}

Note that the third Test here for testGetPriceForProductAssertionError() will result in an assertion error and will not pass as the mock was not activated in that case resulting in an unexpected behavior.

Thanks and Happy Coding !!

Partial Mocks using EasyMock

Often, there arises a situation where we need to mock only specific methods of a certain object and not the entire class. Such a situation can arise when we need to test some methods of a class which are dependent on other methods. We need to mock methods on which the behavior is dependent. Solution is to use partial mocks and to mock only the required methods.

In this post, we will see how this partial mock object can be created using EasyMock. To get familiar with EasyMock, you can refer here.

This is how we can create partial mock objects.
Retailer retailer = EasyMock.createMockBuilder(Retailer.class)
.addMockedMethod("getTaxRate").createMock();
EasyMock.expect(retailer.getTaxRate()).andReturn(20);

The createMockBuilder() creates a mock retailer object with 'getTaxRate' method as mocked. We can add as many methods to mock as required.The behavior of rest of the functions remains same.

We will use the same example used in my previous post. Here is the Customer class which has retailer object as its member -
package com.nirman.easymock;

public class Customer {

 String name;
 Retailer retailer;

 public int getProductPrice(String productId) throws Exception{
  int price = retailer.getPriceForProduct(productId);
  return price;
 }
 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Retailer getRetailer() {
  return retailer;
 }

 public void setRetailer(Retailer retailer) {
  this.retailer = retailer;
 }

}

This is the retailer class -
package com.nirman.easymock;

public class Retailer {

 private int taxes_in_percent = 10;

 public int getPriceForProduct(String productId) throws Exception {
  int price;
  if (productId.equals("101")) {
   price = getPrice(100);
  } else if (productId.equals("102")) {
   price = getPrice(200);
  } else if (productId.equals("103")) {
   price = getPrice(300);
  } else {
   price = 0;
  }
  return price;
 }

 private int getPrice(int basePrice) {
  int finalPrice = basePrice + ((basePrice * getTaxRate()) / 100);
  return finalPrice;
 }

 public int getTaxRate() {
  return taxes_in_percent;
 }
}

Note that the getPrice(int basePrice) internally calls getTaxRate(). We will mock this getTaxRate() and keep rest of the behaviour same.

JUnit-
package com.nirman.easymock;

import org.easymock.EasyMock;
import org.junit.Test;
import org.powermock.reflect.Whitebox;
import static org.junit.Assert.*;

public class TestRetailer {

 // Without any mocks
 @Test
 public void testGetPriceForProduct() throws Exception {
  Customer customer = new Customer();
  Retailer retailer = new Retailer();
  customer.setRetailer(retailer);
  int actual = 0;

  String productId = "101";
  actual = Whitebox. invokeMethod(customer, "getProductPrice",
    productId);

  int expected = 110;
  assertEquals(expected, actual);
 }

 // Partial Mock. Specific method getTaxRate() is mocked
 @Test
 public void testGetPriceForProductPartialMock() throws Exception {
  Customer customer = new Customer();
  Retailer retailer = EasyMock.createMockBuilder(Retailer.class)
    .addMockedMethod("getTaxRate").createMock();
  customer.setRetailer(retailer);
  EasyMock.expect(retailer.getTaxRate()).andReturn(20);
  EasyMock.replay(retailer);
  int actual = 0;

  String productId = "101";
  actual = Whitebox. invokeMethod(customer, "getProductPrice",
    productId);
  int expected = 120;
  assertEquals(expected, actual);
 }

}

You can find the complete source code from here.
Thanks !!

Invoke powershell commands through java

Yes, this is possible ! One can invoke powershell cmdlets from a java program and see the results. Possible solution is to execute the powershell process and run the powershell cmdlets from command line using the java 'Runtime' class. 

One approach is to write powershell scripts and have them executed from the program to see the output. Another way is to provide the command directly as string. This way we can create commands dynamically to execute at run-time as required.

Here is the program-
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ExecuteCommand {

 /**
  * @param args
  * @throws IOException 
  */
 public static void main(String[] args) throws IOException {
  String command = "powershell.exe  $PSVersionTable.PSVersion";
  Process powerShellProcess = Runtime.getRuntime().exec(command);
  powerShellProcess.getOutputStream().close();
  String line;
  System.out.println("Output:");
  BufferedReader stdout = new BufferedReader(new InputStreamReader(
    powerShellProcess.getInputStream()));
  while ((line = stdout.readLine()) != null) {
   System.out.println(line);
  }
  stdout.close();
  System.out.println("Error:");
  BufferedReader stderr = new BufferedReader(new InputStreamReader(
    powerShellProcess.getErrorStream()));
  while ((line = stderr.readLine()) != null) {
   System.out.println(line);
  }
  stderr.close();
  System.out.println("Done");

 }

}

It just finds out the powershell version installed on your machine and displays the result on console.

To execute powershell scripts, we just need to have 
String command = "powershell.exe  \"C:\\PowerShellVersion.ps1\" ";

We need to provide location for the script file to be executed. You can get the source code from here.

Thanks.

Integrity Constraint violated while importing data for unique identifier column in SQL Server

Following is the error message which came up when we tried inserting data from excel sheet into a database table using the Import and Export Wizard -

There was an error with input column "<ColumnName>" (168) on input "Destination Input" (75). The column status returned was: "The value violated the integrity constraints for the column."

The column for which it was showing the error was defined as a unique identifier in the table. 

Such an error can come up when we try to insert string data 'varchar' for unique identifier fields (GUIDs). The simple trick is to enclose these GUIDs (format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) in braces {}.

Thus a GUID string such as {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} in the excel sheet data should get rid of this error !

Wednesday 8 January 2014

Spring Security: Remember me Example

Remember me authentication is a mechanism that allows a user to maintain his identity across multiple browser sessions. Typically, a browser session ends when we close the browser. This means that with Remember-me, a user will be able to automatically login even after he restarts the browser. It remembers the identity of the user between two different sessions.

This is typically accomplished by sending a cookie to the browser, with the cookie being detected during future sessions and causing automated login to take place. Spring Security provides the necessary hooks for these operations to take place, and has two concrete remember-me implementations.  One uses hashing to preserve the security of cookie-based tokens and the other uses a database or other persistent storage mechanism to store the generated tokens. Note that both the implementations require a UserDetailsService. 

1. Simple Hash-Based Token Approach

This approach uses hashing to achieve a useful remember-me strategy. In essence a cookie is sent to the browser upon successful interactive authentication, with the cookie being composed as follows:

base64(username + ":" + expirationTime + ":" + 
md5Hex(username + ":" + expirationTime + ":" password + ":" + key)) 

username: As identifiable to the `UserDetailsService`. 

password: That matches the one in the retrieve UserDetails. 

expirationTime: The date and time when the remember-me token expires, expressed in milliseconds .

key: A private key to prevent modification of the remember-me token.

The remember-me token is valid only for the period specified, and provided that the username, password and key does not change. To enable remember-me authentication just add the <remember-me> element into <http element>

<http> ... <remember-me key="myAppKey"/> </http>


2. Persistent Token Approach

This approach uses the database to store the generated tokens. The database that will be used should contain a persistent_logins table, created using the following SQL (or equivalent):

create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null)

To use this approach with the namespace configuration, you need to supply a datasource reference

<http> ... <remember-me data-source-ref="someDataSource"/> </http>

Example

The setup is the same as the one used for my previous post demonstrating the use of a custom UserDetailsService.

Only changes required are in spring-security.xml configuration. We will be using the Hash-Based token approach. 



 
  

  
  

  

  
 

 
  
 

Demo

If we try to access the URL- '/SpringSecurity/user/welcome'
Spring Security intercepts this URL and presents a login form.

Note that there exists a check-box for remember me.If we tick this check-box and login with valid credentials, a cookie named 'SPRING_SECURITY_REMEMBER_ME' is created along with the cookie storing JSessionId. 




If we delete this cookie for JSessionId, we are still able to login automatically and access the intercepted URL.

This is all because of the simple Hash-Based generated token stored inside the browser's cookie.

You can view/download the complete source code from here.