Posts Tagged ‘junit

11
Apr
10

Annotation based Equals and HashCode Test Case

This page will describe how you can annotate a Java bean so that JUnit verify proper equals() and hashCode() implementations.

Background

The fastest way to implement equals and hash code is to manually code it. The problem with doing it manually is that the code become out of sync.

Solution

Annotate the fields that should be present in the equals and hashCode() methods. JUnit checks these annotations and verifies that the equals() and hashCode() methods are implemented properly. You still need to manually update the equals and hashcode methods if something changes but now at least you have a test case that will fail if something goes wrong.

Requirements

  • Java 5 or better
  • Maven 2 – (Link to a Maven Tutorial available on right navigation)

Implementation

The following example will demonstrate the very basic usage scenario of annotation based unit testing of equals and hashCode methods.

First step is to create a project using maven archetype. Open up the command prompt and navigate to an empty directory.

mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart

groupId: com.test
artifactId: beanUnitTest

Answer the rest of the questions with defaults “Just hit the enter key”

If you are using eclipse then you may want to regenerate your project before importing it into eclipse.
do this by typing:

mvn eclipse:clean eclipse:eclipse

Next define the equals annotation. This annotation will be used to mark the fields that should participate in the equals and hashCode methods.

/src/test/java/com/test/Equals.java

package com.test;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Equals {
}

/src/main/java/com/test/TestBean.java

package com.test;

public class TestBean {
	@Equals
	private String name;
	@Equals
	private String address;
	@Equals
	private boolean drugTestPassed;
	@Equals
	private int age;
	@Equals
	private long birthday;
	@Equals
	private SubBean subBean = new SubBean();

// getters and setters go here...

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((address == null) ? 0 : address.hashCode());
		result = prime * result + age;
		result = prime * result + (int) (birthday ^ (birthday >>> 32));
		result = prime * result + (drugTestPassed ? 1231 : 1237);
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((subBean == null) ? 0 : subBean.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		TestBean other = (TestBean) obj;
		if (address == null) {
			if (other.address != null)
				return false;
		} else if (!address.equals(other.address))
			return false;
		if (age != other.age)
			return false;
		if (birthday != other.birthday)
			return false;
		if (drugTestPassed != other.drugTestPassed)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (subBean == null) {
			if (other.subBean != null)
				return false;
		} else if (!subBean.equals(other.subBean))
			return false;

		return true;
	}
}

src/main/java/com/test/SubBean.java

package com.test;

/**
 * This is a sub bean where only the ID field is used to decide
 * if the object is equal or not.
 *
 */
public class SubBean {

	@Equals
	private Integer id;

	private String name;
	private String age;

// getters and setters...

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		SubBean other = (SubBean) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
}

The following is the heart of the system. It is just an abstract base class that could be extended. It was taken from http://blog.coryfoy.com/2008/05/unit-testing-equals-and-hashcode-of-java-beans/ and modified to utilize the annotation features of Java 5. Also some changes were made to not traverse object attributes (see appendix below for more details).

/src/test/java/com/test/BeanTestCase.java

package com.test;
import junit.framework.TestCase;

import java.lang.reflect.Field;

public abstract class BeanTestCase extends TestCase {

	private static final String TEST_STRING_VAL1 = "Some Value";
	private static final String TEST_STRING_VAL2 = "Some Other Value";

	/**
	 * TODO: currently there is no way to check if there are extra checks in the equal.
	 * TODO: what about testing equals in subclasses?
	 * 
	 * @param classUnderTest
	 */
	public static void _assertMeetsEqualsContract(Class classUnderTest) {
		Object o1;
		Object o2;
		try {
			// Get Instances
			o1 = classUnderTest.newInstance();
			o2 = classUnderTest.newInstance();
			assertTrue(
					"Instances with default constructor not equal (o1.equals(o2))",
					o1.equals(o2));
			assertTrue(
					"Instances with default constructor not equal (o2.equals(o1))",
					o2.equals(o1));

			for (Field field : classUnderTest.getDeclaredFields()) {
	        	if(field.isAnnotationPresent(Equals.class)) {
					// Reset the instances
					o1 = classUnderTest.newInstance();
					o2 = classUnderTest.newInstance();

					field.setAccessible(true);

					// set field it to ValueA

					if (field.getType() == String.class) {
						field.set(o1, TEST_STRING_VAL1);
					} else if (field.getType() == boolean.class) {
						field.setBoolean(o1, true);
					} else if (field.getType().isAssignableFrom(Boolean.class)) {
						field.set(o1, Boolean.TRUE);
					} else if (field.getType() == short.class) {
						field.setShort(o1, (short) 1);
					} else if (field.getType().isAssignableFrom(Short.class)) {
						field.set(o1, Short.valueOf((short)1));
					} else if (field.getType() == long.class) {
						field.setLong(o1, (long) 1);
					} else if (field.getType().isAssignableFrom(Long.class)) {
						field.set(o1, Long.valueOf(1));
					} else if (field.getType() == float.class) {
						field.setFloat(o1, (float) 1);
					} else if (field.getType().isAssignableFrom(Float.class)) {
						field.set(o1, Float.valueOf(1));
					} else if (field.getType() == int.class) {
						field.setInt(o1, 1);
					} else if (field.getType().isAssignableFrom(Integer.class)) {
						field.set(o1, Integer.valueOf(1));
					} else if (field.getType() == byte.class) {
						field.setByte(o1, (byte) 1);
					} else if (field.getType().isAssignableFrom(Byte.class)) {
						field.set(o1, Byte.valueOf((byte)1));
					} else if (field.getType() == char.class) {
						field.setChar(o1, (char) 1);
					} else if (field.getType().isAssignableFrom(Character.class)) {
						field.set(o1, Character.valueOf((char)1));
					} else if (field.getType() == double.class) {
						field.setDouble(o1, (double) 1);
					} else if (field.getType().isAssignableFrom(Double.class)) {
						field.set(o1, Double.valueOf(1));
					} else if (field.getType().isEnum()) {
						field.set(o1, field.getType().getEnumConstants()[0]);
					} else if (Object.class.isAssignableFrom(field.getType())) {
						 System.out.println("got here " + field.getType());
						 field.set(o1, field.getType().newInstance());
						 field.set(o2, null);
					} else {
						fail("Don't know how to set a " + field.getType().getName());
					}

					assertFalse("Instances with o1 having " + field.getName()
							+ " set and o2 having it not set are equal", o1
							.equals(o2));

					field.set(o2, field.get(o1));

					assertTrue(
							"After setting o2 with the value of the object in o1, the two objects in the field are not equal",
							field.get(o1).equals(field.get(o2)));

					assertTrue(
							"Instances with o1 having "
									+ field.getName()
									+ " set and o2 having it set to the same object of type "
									+ field.get(o2).getClass().getName()
									+ " are not equal", o1.equals(o2));

					// set field it to ValueB

					if (field.getType() == String.class) {
						field.set(o2, TEST_STRING_VAL2);
					} else if (field.getType() == boolean.class) {
						field.setBoolean(o2, false);
					} else if (field.getType().isAssignableFrom(Boolean.class)) {
						field.set(o2, Boolean.FALSE);
					} else if (field.getType() == short.class) {
						field.setShort(o2, (short) 0);
					} else if (field.getType().isAssignableFrom(Short.class)) {
						field.set(o2, Short.valueOf((short)0));
					} else if (field.getType() == long.class) {
						field.setLong(o2, (long) 0);
					} else if (field.getType().isAssignableFrom(Long.class)) {
						field.set(o2, Long.valueOf(0));
					} else if (field.getType() == float.class) {
						field.setFloat(o2, (float) 0);
					} else if (field.getType().isAssignableFrom(Float.class)) {
						field.set(o2, Float.valueOf(0));
					} else if (field.getType() == int.class) {
						field.setInt(o2, 0);
					} else if (field.getType().isAssignableFrom(Integer.class)) {
						field.set(o2, Integer.valueOf(0));
					} else if (field.getType() == byte.class) {
						field.setByte(o2, (byte) 0);
					} else if (field.getType().isAssignableFrom(Byte.class)) {
						field.set(o2, Byte.valueOf((byte)0));
					} else if (field.getType() == char.class) {
						field.setChar(o2, (char) 0);
					} else if (field.getType().isAssignableFrom(Character.class)) {
						field.set(o2, Character.valueOf((char)0));
					} else if (field.getType() == double.class) {
						field.setDouble(o2, (double) 0);
					} else if (field.getType().isAssignableFrom(Double.class)) {
						field.set(o2, Double.valueOf(0));
					} else if (field.getType().isEnum()) {
						field.set(o2, field.getType().getEnumConstants()[1]);
					} else if (Object.class.isAssignableFrom(field.getType())) { // if its an object.
						//field.set(o2, field.getType().newInstance());
						field.set(o2, null);
					} else {
						fail("Don't know how to set a " + field.getType().getName());
					}

					// make the final asserts after setting the field to be
					// different.

					assertFalse(
							"After setting o2 with a different object than what is in o1, the two objects in the field are equal. "
									+ "This is after an attempt to walk the fields to make them different",
							field.get(o1).equals(field.get(o2)));
					assertFalse(
							"Instances with o1 having "
									+ field.getName()
									+ " set and o2 having it set to a different object are equal",
							o1.equals(o2));
	        	}
			}

		} catch (InstantiationException e) {
			e.printStackTrace();
			throw new AssertionError(
					"Unable to construct an instance of the class under test");
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new AssertionError(
					"Unable to construct an instance of the class under test");
		}
	}

	
	public static void _assertMeetsHashCodeContract(Class classUnderTest) {
		try {
			for (Field field : classUnderTest.getDeclaredFields()) {
	        	if(field.isAnnotationPresent(Equals.class)) {
					Object o1 = classUnderTest.newInstance();
					int initialHashCode = o1.hashCode();

					field.setAccessible(true);
					if (field.getType() == String.class) {
						field.set(o1, TEST_STRING_VAL1);
					} else if (field.getType() == boolean.class) {
						field.setBoolean(o1, true);
					} else if (field.getType().isAssignableFrom(Boolean.class)) {
						field.set(o1, Boolean.TRUE);
					} else if (field.getType() == short.class) {
						field.setShort(o1, (short) 1);
					} else if (field.getType().isAssignableFrom(Short.class)) {
						field.set(o1, (short)1);
					} else if (field.getType() == long.class) {
						field.setLong(o1, (long) 1);
					} else if (field.getType().isAssignableFrom(Long.class)) {
						field.set(o1, Long.valueOf(1));
					} else if (field.getType() == float.class) {
						field.setFloat(o1, (float) 1);
					} else if (field.getType().isAssignableFrom(Float.class)) {
						field.set(o1, Float.valueOf(1));
					} else if (field.getType() == int.class) {
						field.setInt(o1, 1);
					} else if (field.getType().isAssignableFrom(Integer.class)) {
						field.set(o1, Integer.valueOf(1));
					} else if (field.getType() == byte.class) {
						field.setByte(o1, (byte) 1);
					} else if (field.getType().isAssignableFrom(Byte.class)) {
						field.set(o1, Byte.valueOf((byte)1));
					} else if (field.getType() == char.class) {
						field.setChar(o1, (char) 1);
					} else if (field.getType().isAssignableFrom(Character.class)) {
						field.set(o1, Character.valueOf((char)1));
					} else if (field.getType() == double.class) {
						field.setDouble(o1, (double) 1);
					} else if (field.getType().isAssignableFrom(Double.class)) {
						field.set(o1, Double.valueOf(1));
					} else if (field.getType().isEnum()) {
						field.set(o1, field.getType().getEnumConstants()[0]);
					} else if (Object.class.isAssignableFrom(field.getType())) {
						if(field.get(o1) == null) {
							field.set(o1, field.getType().newInstance());							
						} else {
							field.set(o1, null);
						}
					} else {
						fail("Don't know how to set a " + field.getType().getName());
					}
					int updatedHashCode = o1.hashCode();
					assertFalse(
							"The field "
									+ field.getName()
									+ " was not taken into account for the hashCode contract ",
							initialHashCode == updatedHashCode);
	        		
	        	}
			}
		} catch (InstantiationException e) {
			e.printStackTrace();
			throw new AssertionError(
					"Unable to construct an instance of the class under test");
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new AssertionError(
					"Unable to construct an instance of the class under test");
		}
	}
}

The following test case is designed to test the equals and hashcode of the TestBean class.

src/test/java/com/test/TestBeanTest.java

package com.test;

public class TestBeanTest extends BeanTestCase {

	public void testEqualsContractMet() {
		assertMeetsEqualsContract(TestBean.class);
	}
	public void testHashCodeContractMet() {
		assertMeetsHashCodeContract(TestBean.class);
	}
}

Run the above test case and it should pass.

mvn test

The next class we will extend the TestBean and introduce the open member variable in the sub class. We will write a test case that will check for the proper implementation of the equals and hashcode.

src/main/java/com/test/TestBeanSubClass.java

package com.test;

public class TestBeanSubClass extends TestBean {
	@Equals
	private boolean open;

// getters setters

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + (open ? 1231 : 1237);
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		TestBeanSubClass other = (TestBeanSubClass) obj;
		if (open != other.open)
			return false;
		return true;
	}
}

The following is a test case that will check for the proper implementation of the equals and hashcode method.

src/test/java/com/test/TestBeanSubClassTest.java

package com.test;

public class TestBeanSubClassTest extends BeanTestCase {
	public void testEqualsContractMet2() {
		assertMeetsEqualsContract(TestBeanSubClass.class);
	}
	public void testHashCodeContractMet2() {
		assertMeetsHashCodeContract(TestBeanSubClass.class);
	}
}

References

The implementation here differs from the one described in the following link in the fact that reflection is NOT used during runtime.

http://www.platypusinnovation.com/view.html?id=201

Base implementation of the above code was taken from the following URL.

http://blog.coryfoy.com/2008/05/unit-testing-equals-and-hashcode-of-java-beans/

Library to generate various boilerplate code during runtime.

http://projectlombok.org/

Appendix

Dealing with Object Attributes

Object Attributes are expected to implement their own equals method. The test case that checks the parent’s equals method should not be responsible for checking the equals method of object attributes. Instead it will only check to see if the parent bean’s equals() method calls the sub bean’s equals as part of the comparison if the sub bean was marked with the @Equals annotation. The sub bean should be tested separately using its own test case.

We can check to see if equals method is called by exploiting the contract It has with the system.

  • Contract #1: The equals() method returns true when you pass in the same object reference as an argument. Example: this.equals(this) results in true.
  • Contract #2 The equals() method returns false when you pass in a null as the argument. Example: this.equals(null) results in false.

During our test case we will create 2 instances of TestBean class and set instance of SubBean in both instances to be the same reference. We will call the testBeanA.equals(testBeanB) method and it should return true. We will change one instance of TestBean to have a null reference for the subBean attribute and call the testBeanA.equals(testBeanB) method. It should return false since testBeanA.subBean has a reference and testBeanB.subBean is null.

Example: the following “testBeanA.getSubBean().equals(testBeanB.getSubBean())” will return false

04
Apr
10

Using JMock2 to Unit Test Java Code

This page describes the usage of JMock2 framework with JUnit in order to unit test Java code.

Background

No man is an island. By now most everyone has heard this phrase that means that “Human beings do not thrive when isolated from others.” You can say the same for Java classes. Even in the most well designed systems there are always some sort of dependency on other classes. This makes unit testing difficult. This could be the reason developers are turned off from unit testing (not counting laziness).

The JMock2 Framework allows you to create mock implementations. These mock implementations are coded to to behave in a predefined way by the unit tester, then they are injected into Model classes. The model classes are tricked into thinking that they are dealing with actual implementation classes. This allows the developer to setup specific data scenarios that allow the code to be tested.

To conduct effective unit tests you need to make sure that the data does not change. This means you can’t use the database. This is an absolute requirement for 2 reasons.

  1. The data in the database is not static. Databases are shared resource. Someone can always come and yank the data underneath your test case.
  2. The database is slow. Unit tests should be run often and quickly. A slow running test case will make the developer not want to run the test case.

Following MVC Best Practices

An important aspect of writing test friendly and reliable code is to follow MVC best practices. This means that your View logic must be separated from your model and Controller. In addition the model component should be further broken up into parts. One part has the business logic (Model) and the other has the data access logic. Classes that interact with the database, web services, or File systems are to be called DataManagers or DAO’s.

Dont Test your Data Access Layer

In the grand scheme of things the job of DataManagers or DAO’s are pretty simple. These classes convert data back and fourth between the bean representation and the physical representation (network storage, database, or file system). Once you set them up they will continue to perform that task. Your testing effort should not focus on testing your Data Access Layer.. Let you database, or operating system vendor vendor be responsible for this.

Model Layer

The model layer should contain the business logic for your application. It should not make any assumptions on who is invoking calls on it. For example there must be no reference to the Servlet API in this layer. The model layer should communicate to the Data Access Layer thru interfaces. This is the concept of programming by interfaces.

Testing The Model Layer with JMock2

Once you program by interface you can swap out your data managers with Mock implementations and your model will think it is dealing with the real data manager. Doing things this way tricks your Model into thinking the data is coming from the database. This allow you to setup data scenarios to test specific conditions in your model. You can using code coverage analysis tools like eclEMMA in eclipse to ensure you have reached 100% code coverage in your test cases.

Requirements

  • Basic Understanding of JUnit
  • Basic understanding of Maven (see maven tutorial on the right-nav)
  • Understanding of Programming by Interface

Example Code

The following example will show a very basic usage scenario of Jmock2 with Junit.

First step is to create the project using a maven archetype. Open up the command prompt and navigate to an empty directory.

mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart

groupId: com.test
artifactId: jmockTest

Answer the rest of the questions with defaults “Just hit the enter key”

Modify the pom.xml

Modify the file to look like this…

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.test</groupId>
  <artifactId>jmockTest</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>jmockTest</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  <dependency>
    <groupId>org.jmock</groupId>
    <artifactId>jmock</artifactId>
    <version>2.5.1</version>
    <scope>test</scope>
</dependency>
</dependencies>

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
        </plugins>
</build>
</project>

Save and exit.

If you are using eclipse then you may want to regenerate your project before importing it into eclipse.
do this by typing:
mvn eclipse:clean eclipse:eclipse

src/main/java/com/test/Account.java

package com.test;

import java.math.BigDecimal;

/**
 * Simple POJO bean that represents an account.
 */
public class Account {
	public String getAccountNumber() {
		return accountNumber;
	}
	public void setAccountNumber(String accountNumber) {
		this.accountNumber = accountNumber;
	}
	public BigDecimal getBalance() {
		return balance;
	}
	public void setBalance(BigDecimal balance) {
		this.balance = balance;
	}
	private String accountNumber;
	private BigDecimal balance;
}

src/main/java/com/test/AccountDataManager.java

package com.test;

public interface AccountDataManager {
	public void saveAccount(Account accountA);
	public Account getAccountById(String accountAId);
}

src/main/java/com/test/AccountDataManagerImpl.java

package com.test;

public class AccountDataManagerImpl implements AccountDataManager {
	/**
	 * This code is simple no need to test Vendor JDBC implementation...
	 */
	public void saveAccount(Account accountA) {
		// some JDBC code to save account to database
		// goes here.
	}

	/**
	 * This code is simple no need to test Vendor JDBC implementation...
	 */
	public Account getAccountById(String accountAId) {
		// some JDBC code to get account from database
		// goes here.
		return null;
	}
}

src/main/java/com/test/AccountTransferModel.java

package com.test;

import java.math.BigDecimal;

public interface AccountTransferModel {

	/**
	 * Transfer money from account a to account b. This should be executed from
	 * within a transaction. (See spring framework)
	 *
	 * @param a
	 * @param b
	 */
	public abstract void transferMoney(String accountAId, String accountBId,
			BigDecimal amount);

}

src/main/java/com/test/AccountTransferModelImpl.java

package com.test;

import java.math.BigDecimal;

/**
 * This class is where the business logic is implemented.
 */
public class AccountTransferModelImpl implements AccountTransferModel {
	/**
	 * Since we are using an interface here we will use JMock2 to
	 * implement the below interface with a fake stub class.
	 */
	private AccountDataManager accountDataManager;

	public void setAccountDataManager(AccountDataManager accountDataManager) {
		this.accountDataManager = accountDataManager;
	}

	/**
	 * This is the method we are testing...
	 */
	public void transferMoney(String accountAId, String accountBId, BigDecimal amount) {
		Account accountA = accountDataManager.getAccountById(accountAId);
		Account accountB = accountDataManager.getAccountById(accountBId);

		if(accountA==null) {
			throw new IllegalArgumentException("account does not exist.");
		}
		if(accountB==null) {
			throw new IllegalArgumentException("account does not exist.");
		}

		if(accountA.getBalance().compareTo(amount) < 0 ) {
			throw new IllegalArgumentException("account A does not have enough balance.");
		}
		accountA.setBalance(accountA.getBalance().subtract(amount));
		accountB.setBalance(accountB.getBalance().add(amount));

		accountDataManager.saveAccount(accountA);
		accountDataManager.saveAccount(accountB);

	}
}

Finally we write our test case.

src/test/java/com/test/AppTest.java

package com.test;

import java.math.BigDecimal;

import junit.framework.TestCase;

import org.jmock.Expectations;
import org.jmock.Mockery;

/**
 * Test to check Money Transfers Between Accounts
 */
public class AppTest extends TestCase {

	public void testTransfersMoneyBetweenAccounts() {
		Mockery context = new Mockery();
		final AccountDataManager accountDataManager = context.mock(AccountDataManager.class);
		AccountTransferModelImpl accountTransferModel = new AccountTransferModelImpl();
		accountTransferModel.setAccountDataManager(accountDataManager);

		// setup the data
		final Account accountA = new Account();
		accountA.setAccountNumber("abc123");
		accountA.setBalance(BigDecimal.valueOf(100));

		final Account accountB = new Account();
		accountB.setAccountNumber("xyz123");
		accountB.setBalance(BigDecimal.valueOf(100));

		// set the expectations
		// if this next section looks odd then go visit the jMock2 site
		// for documentation on how to specify expectations
	    context.checking(new Expectations() {{
	        allowing (accountDataManager).getAccountById("abc123");
	        will(returnValue(accountA));
	        allowing (accountDataManager).getAccountById("xyz123");
	        will(returnValue(accountB));

	        oneOf(accountDataManager).saveAccount(accountA);
	        oneOf(accountDataManager).saveAccount(accountB);
	    }});
		// execute the code

	    accountTransferModel.transferMoney("abc123", "xyz123", new BigDecimal(100));

	    // make the assertions
	    assertEquals(accountA.getBalance(),BigDecimal.valueOf(0));
	    assertEquals(accountB.getBalance(),BigDecimal.valueOf(200));
	}
}

Run the code

Run the code by executing it thru eclipse.

Or type mvn test on the command line.

System should return success condition

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.test.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.061 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

Analyse the code

Just Set a couple of breakpoints and trace thru the code using your favorite debugging tool.

References

Thats all for now.




Follow

Get every new post delivered to your Inbox.

Join 49 other followers