Unit testing with EasyMock and Spring
Let's come up with simple test scenario. I have two Spring Service implementations with corresponding interfaces. I like to test only the process method in FooServiceImp class in isolation. 
The problem is FooServiceImp.peocess() calls FooBarService.process() method which I don't want to test with this peticular Unit test.
So how do I test just FooServiceImp.process() method without testing FooBarService. EasyMock is to rescue. Before the testing I can replace the reference of FooBarService to a EasyMock object and add certain expected behavior to the Mock.
Behaviors I like to add to mock:
1. The return value of the Mock service.
2. Capture the parameters passed to the Mock
Service.
3. Add a Exception to test Exception scenario
Here are the codes. Happy Unit Testing:
FooServiceTest.java
FooService.java
FooServiceImp.java
FooBarService.java
FooBarServiceImp.java:
Foo.xml - Spring conf file
The problem is FooServiceImp.peocess() calls FooBarService.process() method which I don't want to test with this peticular Unit test.
So how do I test just FooServiceImp.process() method without testing FooBarService. EasyMock is to rescue. Before the testing I can replace the reference of FooBarService to a EasyMock object and add certain expected behavior to the Mock.
Behaviors I like to add to mock:
1. The return value of the Mock service.
2. Capture the parameters passed to the Mock
Service.
3. Add a Exception to test Exception scenario
Here are the codes. Happy Unit Testing:
FooServiceTest.java
import static org.junit.Assert.*; 
import java.util.List; 
import org.easymock.Capture; 
import org.easymock.EasyMock; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
@ContextConfiguration(locations = { "classpath:Foo.xml" }) 
@RunWith(SpringJUnit4ClassRunner.class) 
public class FooServiceTest 
{ 
//Get a reference of FooServiceImp from Spring contexts 
@Autowired 
FooServiceImp fooService; 
@Before 
public void setUp() 
throws Exception 
{ 
//Replace with EasyMock object 
fooService.fooBarService = EasyMock.createNiceMock(FooBarService.class); 
} 
/* 
* Test the regular scenario 
*/ 
@Test 
public void testFooService() throws Exception{ 
//Creating a input value of String array 
String[] values = {"value1","value2", "value3"}; 
//Create Easymock Capture type to capture the 
Capture<List<String>> captureValues = new Capture<List<String>>(); 
//Setting behavior for the Mock service. 
EasyMock.expect(fooService.fooBarService.process( EasyMock.capture(captureValues))).andReturn("value1"); 
EasyMock.replay(fooService.fooBarService); 
//Test the return value 
assertEquals(fooService.process(values),"value1"); 
EasyMock.verify(fooService.fooBarService); 
//Check the parameters on Mock service call 
assertEquals(captureValues.getValue().get(0),"value1"); 
} 
/* 
* Test the Exception scenario 
*/ 
@Test(expected = Exception.class) 
public void testFooServiceException() throws Exception{ 
EasyMock.reset(fooService.fooBarService); 
String[] values = {"value1","value2", "value3"}; 
Capture<List<String>> captureValues = new Capture<List<String>>();  
//Setting the expected Exception on the Mock service 
EasyMock.expect(fooService.fooBarService.process( EasyMock.capture(captureValues))).andThrow(new Exception()); 
EasyMock.replay(fooService.fooBarService); 
//Should get an exception to pass the test 
fooService.process(values); 
} 
} 
FooService.java
public interface FooService 
{ 
public String process(String[] values) throws Exception; 
} 
FooServiceImp.java
import java.util.Arrays; 
import java.util.List; 
import org.springframework.beans.factory.annotation.Autowired; 
public class FooServiceImp 
implements FooService 
{ 
@Autowired 
FooBarService fooBarService; 
@Override 
public String process(String[] values) throws Exception 
{ 
List<string> arrayList = Arrays.asList(values); 
System.out.println(arrayList); 
return fooBarService.process((List<string>)Arrays.asList(values)); 
} 
} 
FooBarService.java
import java.util.List; 
public interface FooBarService 
{ 
public String process(List<String> values) throws Exception; 
} 
FooBarServiceImp.java:
import java.util.List; 
public class FooBarServiceImp 
implements FooBarService 
{ 
@Override 
public String process(List<String> values) throws Exception 
{ 
System.out.println("In FooBar" + values.get(0)); 
return values.get(0); 
} 
} 
Foo.xml - Spring conf file
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:amq="http://activemq.apache.org/schema/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <bean id="fooService" primary="true" class="com.icrossing.service.FooServiceImp"> </bean> <bean id="fooBarService" primary="true" class="com.icrossing.service.FooBarServiceImp"> </bean> </beans>
Comments
Post a Comment