Mockito For Spring - Sample Chapter
Mockito For Spring - Sample Chapter
ee
Sa
pl
This book is not only about the Spring Framework. It also describes the
basics of Spring, Spring's test module, Spring's integration testing, JUnit
testing, how to mock Spring beans with Mockito, and advanced Spring
4.1 features. I couldn't find any books that cover these topics.
This book explains JUnit testing and mocking in the context of Spring.
The book covers Spring's test module and Spring integration testing in
detail. These are the most difficult parts in the Spring testing world. I have
taken a hands-on approach here by combining theories with examples
to explain the topics.
Spring projects
Spring JDBC
Transaction management
Spring MVC
A Java method can handle an HTTP POST/GET request; you don't have to
write a servlet or work with servlet APIs
A Java method can act as a RESTful web service without dealing with web
service APIs
A Java method can consume or handle messages without having to deal with
JMS APIs
Non-invasive (POJO-based)
Modular
[8]
Chapter 1
There are various Spring projects that can be used. In this book, we'll be using
Spring 4.
The following are the icons of some Spring projects:
IO PLATFORM
BOOT
SPRING FRAMEWORK SPRING XD
SPRING CLOUD
SPRING DATA
INTEGRATION
BATCH
The Spring IO platform: Spring IO brings together the core Spring APIs into
a cohesive and versioned foundational platform for modern applications.
Spring IO is comprised of the Spring IO Foundation and Spring IO
Execution layers.
Spring XD: This is a unified, distributed, and extensible system for data
ingestion, real-time analytics, batch processing, and data export. The goal
of the project is to simplify the development of big data applications.
Spring Data: This simplifies data access, offers APIs to work with the
relational databases, NoSQL or non-relational databases, big data or
the map-reduce algorithm, and so on.
[9]
SECURITY
SPRING HATEOAS
SPRING MOBILE
ANDROID
SPRING SOCIAL
WEB FLOW
SPRING AMQP
SPRING LDAP
WEB SERVICES
GRAILS
Spring Mobile: This is an extension to Spring MVC that aims to simplify the
development of mobile web applications.
Chapter 1
Core and Beans: These provide the fundamental parts of the framework,
including IoC and dependency injection features
Portlet: This module (also known as the web-portlet module) provides the
MVC implementation to be used in a portlet environment and mirrors the
functionality of the webmvc module.
Chapter 1
Web
JDBC
ORM
OXM
JMS
WebSocket
Servlet
Web
Portlet
Transactions
Messaging
Aspects
AOP
Instrumentation
Core Container
Beans
Core
Context
SpEL
Test
[ 13 ]
[ 14 ]
Chapter 1
To refactor this tight coupling, we can move the BookService instantiation to the
constructor of the class. The following is the modified BookLister class:
public class BookLister {
private final BookService bookFinder;
public BookLister(BookService bookFinder) {
this.bookFinder = bookFinder;
}
public List<Book> findByAuthor(String author){
List<Book> books = new ArrayList<>();
for(Book aBook:bookFinder.findAll()){
for(String anAuthor:aBook.getAuthors()){
if(anAuthor.equals(author)){
books.add(aBook);
break;
}
}
}
return books;
}
}
Constructor injection
Setter injection
[ 15 ]
The setter injection is carried out by setting a property. In a setter injection, instead
of passing bookService as a constructor argument, we change the class to pass as
a setter method argument.
The Spring configuration is as follows:
<bean id="bookListerSetterInjection" class="com.packt.di.BookLister">
<property name="bookService" ref="bookService" />
</bean>
<bean id="bookService" class="com.packt.di.BookServiceImpl" />
The Spring IoC container is known as ApplicationContext. The objects that are
used in our application, defined in ApplicationContext, and managed by the
Spring IoC container are called beans; for example, bookService is a bean.
A bean is an object that is managed by the Spring IoC container; beans are created
with the configuration metadata that you supply to the container, such as in the
form of XML <bean/> definitions or using Java annotations.
A bean definition describes a bean instance. The bean definition contains the
information called configuration metadata, which is needed by the container to know
how to create the bean, the life cycle of the bean, and the dependencies of the bean.
[ 16 ]
Chapter 1
class: This is mandatory and provides the fully qualified bean class name
scope: This provides the scope of the objects created from a bean definition,
such as prototype and singleton. We'll learn about them later.
lazy-init: If this is set as true, the IoC container creates the bean
instance when it is first requested, rather than at startup, which means any
configuration error is not discovered until the bean is eventually instantiated
inside the Spring context.
init-method: This provides the method name of the bean that is being
invoked just after all necessary properties on the bean are set by the IoC
container. This is useful when we need to initialize/compute something
after the bean is instantiated.
singleton: A single instance of the bean per IoC container. This is not
request: A bean instance per HTTP request, only valid in the web-aware
session: A bean instance per HTTP session, only valid in the web-aware
global-session: A bean instance per global HTTP session, only valid in the
actually the same as in the singleton design pattern (that is, one instance
per classloader).
A new bean instance is created each time one is needed.
application context.
application context.
[ 17 ]
Instantiate
ApplicationContextAwares
setApplicationContext( )
call custom
init-method
Bean is Ready
to use
container
shuts down
BeanNameAwares
setBeanName()
BeanFactoryAwares
setBeanFactory()
Pre-initialization
BeanPostProcessors
InitializingBeans
afterPropertiesSet()
Pre-initialization
BeanPostProcessors
DisposableBeans
destroy()
Call custom
destroy-method
To learn more about DI and IoC, visit the Martin Fowler site at
http://martinfowler.com/articles/injection.html.
[ 18 ]
Chapter 1
[ 19 ]
We load the Spring bean configuration from an XML file, which is kept
in the classpath and named applicationContext.xml, and then ask the
context to find a bean with a name or ID as helloWorld. Finally, we call
the getMessage() method on the bean to check the value we set in the
application context.
[ 20 ]
Chapter 1
Add the System.out.println statement in all the implemented methods. Now, add
the following two methods:
public void myInit() {
System.out.println("custom myInit is called ");
}
public void myDestroy() {
System.out.println("custom myDestroy is called ");
}
[ 21 ]
Modify the bean definition to call the init-method and destroy-method methods.
The following is the modified bean definition:
<bean id="helloWorld" class="com.packt.lifecycle.HelloWorld"
init-method="myInit" destroy-method="myDestroy">
<property name="message" value="Welcome to the Spring world">
</property>
</bean>
Note that the setBeanName method is invoked first, then the setBeanFactory,
setApplicationContext, and afterProperiesSet methods are called, and then the
custom init method is invoked. During destruction, the destroy method is called
first and then the custom destroy-method is invoked.
byName: The container tries to match and wire bean properties with the beans
defined by the same name in the configuration file.
[ 22 ]
Chapter 1
byType: The container tries to match a property if its type matches with
exactly one of the bean names in the configuration file. If more than one
such bean exists, an exception is thrown.
[ 23 ]
Modify the HelloWorld class to annotate the setter method (setMessage) or the
private message property with @Autowired:
public class HelloWorld implements ApplicationContextAware,BeanNameAwa
re, InitializingBean,
BeanFactoryAware,BeanPostProcessor, DisposableBean {
private String message;
public String getMessage() {
return message;
}
@Autowired
public void setMessage(String message) {
this.message = message;
}
//code omitted for brevity
}
Rerun the application; you will see the auto wired message.
[ 24 ]
Chapter 1
Transaction management
Security
Caching
Error handling
Performance monitoring
Event handling
AspectJ: This is the original AOP technology (the first version dates from
1995) that offers a full-blown, aspect-oriented programming language and
uses bytecode modification for aspect weaving.
[ 25 ]
Method invocation
Class initialization
Object initialization
Advice: This is the code that is executed at a specific join point. The three
types of advice are as follows:
Weaving: This is the process of applying aspects into the code at the
appropriate join points. There are three types of weaving:
Compile-time weaving
Runtime weaving
[ 26 ]
Chapter 1
Introduction: This is the process by which you can modify the structure
of an object by introducing additional methods or fields to it. You use the
introduction to make any object implement a specific interface without
needing the object's class to implement that interface explicitly.
Static AOP
The weaving process forms another step in the build process for
an application
For example, in a Java program, you can achieve the weaving process
by modifying the actual bytecode of the application by changing and
modifying the code as necessary
Dynamic AOP
Spring AOP is based on proxies. To know more about proxies, read about the proxy
pattern or visit http://en.wikipedia.org/wiki/Proxy_pattern.
We'll display Hello World! through AOP. The following are the steps to create the
hello world message:
1. Create an interface called IMessageWriter:
package com.packt.aop;
public interface IMessageWriter {
void writeMessage();
}
4. We'll use the ProxyFactory class to create the proxy of the target object:
import org.springframework.aop.framework.ProxyFactory;
public class AOPTest {
public static void main(String[] args) {
MessageWriter target = new MessageWriter();
// create the proxy
ProxyFactory pf = new ProxyFactory();
// Add the given AOP Alliance advice to the tail
// of the advice (interceptor) chain
pf.addAdvice(new MessageDecorator());
// Set the given object as target
pf.setTarget(target);
// Create a new proxy according to the
// settings in this factory
MessageWriter proxy = (MessageWriter)
pf.getProxy();
// write the messages
target.writeMessage();
System.out.println("");
// use the proxy
proxy.writeMessage();
}
}
[ 28 ]
Chapter 1
When we run the program, the MessageDecorator around advice is applied on the
proxy object. When proxy.writeMessage is called, the correct output is displayed.
JdbcDaoSupport
HibernateDaoSupport
JdoDaoSupport
JpaDaoSupport
In normal JDBC code, we write the code in the following way to access the database:
1. Define the connection parameters.
2. Open the connection.
3. Specify the statement.
4. Prepare and execute the statement.
5. Set up the loop to iterate through the results (if any).
6. Do the work for each iteration.
7. Process any exception.
8. Handle transactions.
9. Close the connection.
[ 29 ]
Spring Framework relaxes the requirement to write numerous JDBC code lines. We
need to write only the code to perform the following:
Spring takes care of all the grungy, low-level details that can make JDBC such a
tedious API to develop against.
The Spring-JDBC abstraction framework consists of four different packages:
org.springframework.jdbc.core
org.springframework.jdbc.datasource
org.springframework.jdbc.object
org.springframework.jdbc.support
Various simple DataSource implementations that can be used to test and run
unmodified JDBC code outside of a J2EE container
The utility class provides static methods to obtain connections from JNDI and
to close connections if necessary
[ 30 ]
Chapter 1
The code using the Spring JDBC abstraction layer does not need to
implement JDBC-or RDBMS-specific error handling
All translated exceptions are unchecked giving you the option of catching the
exceptions that you can recover from while allowing other exceptions to be
propagated to the caller
Download the latest version of the Spring JDBC JAR and its dependencies from
http://maven.springframework.org/release/org/springframework/spring/.
[ 31 ]
Perform the following steps to implement Spring JDBC and simplify the code:
1. Launch Eclipse and create a Java project named DatabaseAccess.
2. Add a class PhoneEntry to store phone details. The following are the
class details:
package com.packt.database.model;
public class PhoneEntry implements Serializable {
private static final long serialVersionUID = 1L;
private String phoneNumber;
private String firstName;
private String lastName;
// getters and setters
}
3. Create a data access interface for the phone book. The following are
the API details:
package com.packt.database.dao;
import java.util.List;
import com.packt.database.model.PhoneEntry;
public interface PhoneBookDao {
boolean create(PhoneEntry entry);
boolean update(PhoneEntry entryToUpdate);
List<PhoneEntry> searchByNumber(String number);
List<PhoneEntry> searchByFirstName(String firstName);
List<PhoneEntry> searchByLastName(String lastName);
boolean delete(String number);
}
[ 32 ]
Chapter 1
[ 33 ]
[ 34 ]
Chapter 1
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return false;
}
implements
[ 35 ]
The JdbcTemplate class simplifies the use of JDBC; it handles the resources
and helps avoid common errors such as not closing the connection. It
creates and populates the statement object, iterates through ResultSet,
leaving the application code to provide SQL and extract results.
PhoneBookDerbySpringDao contains a JdbcTemplate instance and delegates
the database tasks to jdbcTemplate. JdbcTemplate uses data source
definition from the applicationContext file.
JdbcTemplate has an update method for the insert and update operations. It
takes a SQL query and parameters. The new Spring version of the create()
method invokes the update() method on jdbcTemplate and passes the
PhoneEntry details. Now the create method looks simple; it is just two
lines of code. Spring Framework handles the resource life cycle.
Look at the Spring DAO class; it has only 54 lines. The class looks neat,
simple, and readable. It doesn't handle resources; rather, it concentrates
on data access.
Two transaction management options are available for the J2EE developers.
The following are the two options:
Chapter 1
Spring's transaction model solves the problems associated with the global and
local transactions, and it offers a consistent programming model for developers
that can be used in any environment.
Spring Framework supports both declarative and programmatic transaction
management. Declarative transaction management is the recommended one,
and it has been well accepted by the development community.
The programmatic transaction model provides an abstraction that can be run over
any underlying transaction infrastructure. The concept of transaction strategy is
the key to the transaction abstraction. The org.springframework.transaction.
PlatformTransactionManager interface defines the strategy.
The following is the PlatformTransactionManager interface:
public interface PlatformTransactionManager {
TransactionStatus getTransaction(
TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws
TransactionException;
void rollback(TransactionStatus status) throws
TransactionException;
}
[ 37 ]
Isolation: This returns the degree of isolation of this transaction from other
transactions. The following are the Spring propagations:
ISOLATION_DEFAULT
ISOLATION_READ_COMMITTED
ISOLATION_READ_UNCOMMITTED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE
a nested transaction
transaction exists
[ 38 ]
Chapter 1
Timeout: This returns the maximum time in seconds that the current
transaction should take; if the transaction takes more than that, then the
transaction gets rolled back automatically.
Here, ${jdbc.xxxx} represents the values defined in the properties file. Usually,
the convention is that the JDBC properties are defined in a properties file that
is then loaded from applicationContext, and then the JDBC properties are
accessed using the key such as ${key}. The following is the XML configuration
of transaction manager:
<bean id="txManager" class="org.springframework.jdbc.datasource.
DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
[ 39 ]
When we use JTA in a J2EE container and use a container DataSource obtained
via the JNDI lookup, in conjunction with Spring's JtaTransactionManager, then
JtaTransactionManager doesn't need to know about DataSource, or any other
specific resources, as it will use the container's global transaction management
infrastructure.
The following is the JtaTransactionManager definition in Spring context:
<jee:jndi-lookup id="dataSource" jndi-name="myDataSource "/>
<bean id="txManager" class="org.springframework.transaction.jta.
JtaTransactionManager"/>
The benefit of Spring transaction manager is that in all cases, the application code
will not need to change at all. We can change how transactions are managed merely
by changing the configuration, even if that change means moving from local to
global transactions or vice versa.
Declarative transaction management is preferred by most users; it is the option with
the least impact on the application code. It is most consistent with the ideals of a
non-invasive lightweight container. Spring's declarative transaction management is
made possible with Spring AOP.
The similarities between the EJB CMT and Spring declarative transaction are
as follows:
[ 40 ]
Chapter 1
Define an advice with transaction manager so that all get methods will have
a read-only transaction:
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!--all methods starting with 'get' are read-only-->
<tx:method name="get*" read-only="true" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>
5. Create a test class to get the FooService bean and call the getFoo method on
the FooService bean. The following is the class:
public class TransactionTest {
public static void main(String[] args) {
AbstractApplicationContext context = new
ClassPathXmlApplicationContext(
"applicationContextTx.xml");
FooService fooService = (FooService)
context.getBean("fooService");
[ 42 ]
Chapter 1
System.out.println(fooService);
fooService.getFoo(null);
}
}
6. When we run the program, Spring creates a transaction and then rolls back
the transaction as it throws UnsupportedOperationException. Check the
log to get the details. The following is the log:
- Creating new transaction with name [com.packt.tx.FooServiceImpl.
getFoo]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
- Acquired Connection [341280385, URL=jdbc:derby:derbyDB,
UserName=dbo, Apache Derby Embedded JDBC Driver] for JDBC
transaction
- Setting JDBC Connection [341280385, URL=jdbc:derby:derbyDB,
UserName=dbo, Apache Derby Embedded JDBC Driver] read-only
- Switching JDBC Connection [341280385, URL=jdbc:derby:derbyDB,
UserName=dbo, Apache Derby Embedded JDBC Driver] to manual commit
- Bound value [org.springframework.jdbc.datasource.
ConnectionHolder@6b58ba2b] for key [org.apache.commons.dbcp2.
BasicDataSource@680624c7] to thread [main]
- Initializing transaction synchronization
- Getting transaction for [com.packt.tx.FooServiceImpl.getFoo]
- Completing transaction for [com.packt.tx.FooServiceImpl.getFoo]
after exception: java.lang.UnsupportedOperationException
- Applying rules to determine whether transaction should rollback
on java.lang.UnsupportedOperationException
- Winning rollback rule is: null
- No relevant rollback rule found: applying default rules
- Triggering beforeCompletion synchronization
- Initiating transaction rollback
- Rolling back JDBC transaction on Connection [341280385,
URL=jdbc:derby:derbyDB, UserName=dbo, Apache Derby Embedded JDBC
Driver]
[ 43 ]
exists, the method will run in that, and if not, a new transaction will be created.
The read-only attribute specifies that the transaction is only going to read data
from a database. It can be applied to only those propagation settings that start a
transaction, that is, PROPAGATION_REQUIRED, PROPAGATION_REQUIRES_NEW, and
PROPAGATION_NESTED.
[ 44 ]
Chapter 1
The timeout specifies the maximum time allowed for a transaction to run. This is
required for the transactions that run for very long and hold locks for a long time.
When a transaction reaches the timeout period, it is rolled back. The timeout needs
to be specified only on propagation settings that start a new transaction.
We can specify that transactions will roll back on certain exceptions and do not roll
back on other exceptions by specifying the rollback rules.
[ 45 ]
When the previous POJO is defined as a bean in a Spring IoC container, the bean
instance can be made transactional by adding one line of XML configuration. We'll
examine the @Transactional annotation in the following example:
1. Create a application context file called applicationContextTxAnnotation.
xml and add the following lines (no need for aop and advice):
<context:annotation-config />
<bean id="fooService" class="com.packt.tx.FooServiceImpl" />
<!-- enable the configuration of transactional behavior based on
annotations -->
<tx:annotation-driven transaction-manager="txManager" />
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="url"
value="jdbc:derby:derbyDB;create=true" />
<property name="username" value="dbo" />
<property name="password" value="" />
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource
.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
[ 46 ]
Chapter 1
@Override public void insertFoo(Foo foo) {
throw new UnsupportedOperationException();
}
@Override public void updateFoo(Foo foo) {
throw new UnsupportedOperationException();
}
}
Using TransactionTemplate
[ 47 ]
Using TransactionTemplate
The following are the characteristics of TransactionTemplate:
Using PlatformTransactionManager
A PlatformTransactionManager implementation can be directly used to manage
a transaction:
1. Simply pass the implementation of the PlatformTransactionManager
to your bean via a bean reference.
2. Then, using the TransactionDefinition and TransactionStatus objects,
you can initiate transactions and perform a rollback or commit.
[ 48 ]
Chapter 1
[ 49 ]
Dependency injection
Interface-driven design
Form validation
Error handling
Page workflow
[ 50 ]
Chapter 1
The following sequence diagram represents the flow and interaction of Spring
MVC components:
:Browser
:DispatcherServlet
request
:HandlerMapping
:Controller
:ViewResolver
:View
request
controller
request
model and logical view
information
view name
view
request [mode]
renders the model
We will build a Spring web application and unit test code using JUnit by performing
the following steps:
1. Launch Eclipse and create a dynamic web project called SpringMvcTest.
2. Open web.xml and enter the following lines:
<display-name>SpringMVCTest</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml
</param-value>
</context-param>
</web-app>
[ 51 ]
This XML defines a Spring view resolver. Any view will be found under the
/WEB-INF/pages location with the .jsp suffix, and all beans are configured
under the com.packt package with Spring annotations.
4. Create a LoginInfo class in the com.packt.model package. This class
represents the login information. Add two private string fields, userId
and password, generate getters and setters
5. Create a JSP page called login.jsp under /WEB-INF/pages and add the
following lines to create a form using the Spring tag library. Modify the
form and add normal HTML input for username and password:
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/
form"%>
<sf:form method="POST" modelAttribute="loginInfo" action="/
onLogin">
</sf:form>
[ 52 ]
Chapter 1
[ 53 ]
Also, add the following JSTL expression to display the error message:
<h1>${error}</h1>
9. Create a JSP file called greetings.jsp and add the following lines:
<h1>Hello :${name}</h1>
Summary
This chapter covered the Spring basics. It discussed the Spring projects and in
particular Spring Framework. It explored the Spring container, Spring bean life cycle,
dependency injection, AOP, Spring MVC, and Spring transaction management.
The next chapter will focus on getting the reader quickly started with JUnit 4 and
the Mocking framework. It provides an overview of JUnit testing and explores the
Mockito APIs.
[ 54 ]
www.PacktPub.com
Stay Connected: