Sunday, 20 July 2014

Testing Java programs with EasyMock and JUnit

Background

EasyMock has been the first dynamic Mock Object generator, relieving users of hand-writing Mock Objects, or generating code for them.

EasyMock provides Mock Objects by generating them on the fly using Java's proxy mechanism.

We are going to use this to write test cases in Java. For more details you can visit their official website.


Adding Dependencies

As usual I am going to use Ivy to add dependencies to my project (Installing and using Apache Ivy as dependency manager).  You ivy.xml should look something like the following - 

<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF licenses this file
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.    
-->
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
    <info
        organisation="openSourceForGeeks"
        module="EasyMockDemo"
        status="integration">
    </info>

    <dependencies>
        <dependency org="junit" name="junit" rev="4.11"/>
        <dependency org="org.easymock" name="easymock" rev="3.1"/>
        
    </dependencies>

</ivy-module>


What we want to achieve via this testing and Why...

Consider you have developed a online shopping portal. You have a class Product that holds information of your individual product like  its name and quantity. When you shop you would purchase multiple products. So lets have a class ShoppingBasket that holds a List of Products. Also lets have a service ShoppingService that would calculate total cost of all the product in the ShoppingBasket. In production code you would probably have this service make a database call the get the price of the product but we cannot afford that in the tests. So we will mock this service and use it instead of an actual DB call.


To the code.....

First create a class Product.java

public class Product {
    
    private String name;
    private int quantity;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getQuantity() {
        return quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

}


Then create a class name ShoppingBasket.java

public class ShoppingBasket {
    
    private String basketName;
    private ShoppingService shoppingService;
    
    private List<Product> products = new ArrayList<Product>();
    
    public int getTotalCost() {
        int totalCost = 0;
        for(Product product: products) {
            totalCost = totalCost + shoppingService.getProductCost(product.getName());
        }
        return totalCost;
    }
    
    public void addProduct(Product product) {
        this.products.add(product);
    }

    public String getBasketName() {
        return basketName;
    }

    public void setBasketName(String basketName) {
        this.basketName = basketName;
    }

    public ShoppingService getShoppingService() {
        return shoppingService;
    }

    public void setShoppingService(ShoppingService shoppingService) {
        this.shoppingService = shoppingService;
    }

    public List<Product> getProducts() {
        return products;
    }

    public void setProducts(List<Product> products) {
        this.products = products;
    } 

}


Noe create a Service (which would be an interface / production code would have this implementation with DB logic) name ShoppingService.java.

public interface ShoppingService {
    
    int getProductCost(String productName);
    
}

Note : Methods in an interface are bu default public and abstract. Whereas variable are by default public, static and final.

Finally create a Test class that mocks the service and tests out the getProductCost() method.

import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import junit.framework.Assert;

import junit.framework.TestCase;


public class ShoppingBasketTest{
    
    private ShoppingBasket shoppingBasket;
    private ShoppingService shoppingServiceMock;
    
    @Before
    public void init(){
        shoppingBasket = new ShoppingBasket();
        shoppingBasket.setBasketName("myBaset");
        shoppingServiceMock = EasyMock.createMock(ShoppingService.class);
        shoppingBasket.setShoppingService(shoppingServiceMock);
    }
    
    @Test
    public void testTotalCost(){
        EasyMock.expect(shoppingServiceMock.getProductCost("Moto E Android Smartphone")).andReturn(7000);
        EasyMock.replay(shoppingServiceMock);
        
        Product motoE = new Product();
        motoE.setName("Moto E Android Smartphone");
        shoppingBasket.addProduct(motoE);
        Assert.assertEquals(7000, shoppingBasket.getTotalCost());
    }

} 
Thats it run the method with annotation @test  using junit. Your test should be successful.





Note : If you make your test class extend TestCase class @before annotation will not work. If you extend TestCase, JUnit treats your test class as an old (pre JUnit 4 class) and picks org.junit.internal.runners.JUnit38ClassRunner to run it. JUnit38ClassRunner does not know about @BeforeClass annotation. You have to put you logic in overridden method setUp().

Monday, 14 July 2014

Using AirDroid to transfer files to and from your android device

Just came across this cool app to transfer data to and from your android smart phone. No cable required. All you need is your device and PC/Laptop to be on the same network.

  1. Install AirDroid - Best Device Manager.
  2. Opem the App and you should see a screen with a URL. It will look something like below -


  3. Next type the given URL in the browser of your Laptop/PC. You will get a request on your device to authenticate the connection.

  4. Then you can see your phone stats and file. You can then transfer files.

  5. You can do lot of other cool stuff like file transfer, view contacts, transfer apps use camera etc. Do explore it...

Saturday, 12 July 2014

How to sort a Map on the values in Java?

Goal

In this post we will see how can we sort a Map based on its values. We will use Comparators.

Map overview in Java - 


Code :

 /*
 * author : athakur
 */

public class HelloWorld {


    public static void main(String args[]) {
       
        Map<String,Integer> nameAgeMap = new HashMap<String,Integer>();
        AgeComparator ageComparator =  new AgeComparator(nameAgeMap);
        Map<String,Integer> sortedNameAgeMap = new TreeMap<String,Integer>(ageComparator);

        nameAgeMap.put("Name1",21);
        nameAgeMap.put("Name2",16);
        nameAgeMap.put("Name3",10);
        nameAgeMap.put("Name4",23);

        System.out.println("Original Map : "+ nameAgeMap);
       
        sortedNameAgeMap.putAll(nameAgeMap);

        System.out.println("Sorted Name Age Map : "+ sortedNameAgeMap);
       
    }

}

class AgeComparator implements Comparator<String> {
   
    Map<String,Integer> mapToBeCompared;
   
    public AgeComparator(Map<String,Integer> mapToBeCompared){
        this.mapToBeCompared = mapToBeCompared;
    }

    @Override
    public int compare(String o1, String o2) {
        Integer x = mapToBeCompared.get(o1);
        Integer y = mapToBeCompared.get(o2);
        if(x >= y) {
            return 1;
        }
        else {
            return -1;
        }
    }
   
}


Output :


The output is as expected

Original Map : {Name4=23, Name3=10, Name2=16, Name1=21}
Sorted Name Age Map : {Name3=10, Name2=16, Name1=21, Name4=23}

 Note

  1. Above comparator imposes orderings that are inconsistent with equals. 
  2. Do not return 0 from the comparator as it will merge the keys. Given that all keys in a Map are unique. Duplicate key entry over writes the old entry.
  3. If you have your own class instead of Integer in the map then it makes sense for your class to implement comparable interface and use compareTo() directly in compare() method. 
  4. Collection APIs provide sort method that takes comparator as an argument. You can use that for the sorting criteria that suits your requirement. 
To summarize if you want to sort objects based on natural order then use Comparable in Java and if you want to sort on some other attribute of object then use Comparator in Java.

Important Links

Sunday, 6 July 2014

Installing Mercurial on Linux

Background

There are many source code versioning tools. Some of them which I have previously used are perforce(p4), git, svn. There are more like cvs, mercurial and the list goes on.... In this post we will see how to install and configure mercurial.

Mercurial is a free, distributed source control management tool. It efficiently handles projects of any size and offers an easy and intuitive interface. (official site)

Mercurial is a cross-platform, distributed revision control tool for software developers. It is mainly implemented using the Python programming language, but includes a binary diff implementation written in C. It is supported on MS Windows and Unix-like systems, such as FreeBSD, Mac OS X and Linux. Mercurial is primarily a command line program but graphical user interface extensions are available. All of Mercurial's operations are invoked as arguments to its driver program hg, a reference to the chemical symbol of the element mercury. (More on Wiki)

Installation

You can easily to the installation using a package manager

sudo apt-get install mercurial

But for me it installed a very old version (2.0.2) which is clearly not the way to go. So you can install the latest version as follows - 


sudo apt-get install python-setuptools python-dev build-essential
sudo easy_install -U mercurial

This installed the latest version for me (3.0.1). You can view the version installed by

hg version


Configuration file for the same can be found in  /etc/mercurial/hgrc. You can edit it to suit your requirements.

I have added external diff program called kdiff3 ( How to Install Kdiff3 on Ubuntu  ). So my hgrc file contents are as follows

# system-wide mercurial configuration file
# See hgrc(5) for more information

[merge-tools]
kdiff3.args=--auto -L1 base --L2 local --L3 other $base $local $other -o $output
kdiff3.regkey=Software\KDiff3
kdiff3.regappend=\kdiff3.exe
kdiff3.fixeol=True
kdiff3.gui=True 

Important Links

How to Install Kdiff3 on Ubuntu

Background

Subversion, Git, Mercurial and others support three-way merges (combining mine, theirs, and the "base" revision) and support graphical tools to resolve conflicts.

Which tool do we use ?  In this post I will show how can we install KDiff3.
 It is an open source cross platform tool.


 

Installation

  1. Download the Kdiff3 tar file from the sourceforge repos, then extract the tar file. The sourceforge link for the Kdiff3 project.
  2. Extract the tar.gz file using tar command

    tar -xzf kdiff3-0.9.98.tar.gz
  3. Make sure you have QT4 installed . If not installed you can install it with following command -

    sudo apt-get install libqt4-dev
  4. After extracting go into the “src-QT4″ directory and compile

    cd kdiff3-0.9.98/src-QT4
    qmake kdiff3.pro
    make
    sudo make install
  5. Now you should be able to launch the program by typing kdiff3 in the console.




Important Links

t> UA-39527780-1 back to top