+ All Categories
Home > Documents > Training - Day 4

Training - Day 4

Date post: 31-Jan-2016
Category:
Upload: teague
View: 34 times
Download: 0 times
Share this document with a friend
Description:
Training - Day 4. The Spring Framework & Testing Web Applications. “Spring's main aim is to make J2EE easier to use and promote good programming practice. It does this by enabling a POJO-based programming model that is applicable in a wide range of environments.” - PowerPoint PPT Presentation
79
Training - Day 4 The Spring Framework & Testing Web Applications
Transcript
Page 1: Training - Day 4

Training - Day 4

The Spring Framework

&

Testing Web Applications

Page 2: Training - Day 4

What does Spring do?

“Spring's main aim is to make J2EE easier to use and promote good programming practice. It does this by enabling a POJO-based programming model that is applicable in a wide range of environments.”

- Rod Johnson

Page 3: Training - Day 4

What it does not do

• No logging API• No connection pools• No O/R mapping layer

• It does not reinvent the wheel. There are great projects that solve these problems and Spring’s goal is to make them easy to use.

Page 4: Training - Day 4

Spring is an IoC Container

• Inversion of Control– Spring’s bean factory, which allows objects to be retrieved

by name• Singleton – one shared object in the factory (Default)• Prototype – the factory will always create a new object

• Dependency Injection… a better name.– “Don’t call me, I’ll call you!”– Takes the responsibility of making things happen away from

the application code and moves it into the framework

Page 5: Training - Day 4

Dependency Injection

• No Spring API intrusion in your code if you don’t want it

• Objects, or dependencies, are injected using ordinary Java method calls

• Configured in XML and injected at runtime

Page 6: Training - Day 4

Types of Dependency Injection

• Setter Injection– Uses JavaBean setter methods– Probably used more often

• Constructor Injection– Uses constructor arguments– Useful in special cases where objects need to do

work in constructors

• Both types can be mixed

Page 7: Training - Day 4

What are the benefits?

• Developers don’t have to worry about looking dependencies up…such as JNDI in EJB projects.

• Easier to test. Simple JavaBean setters are easier to mock than a JNDI service.

• Promotes strong typing.

Page 8: Training - Day 4

Benefits continued…

• Dependencies are explicit in the configuration… no need to read the code to determine application configuration.

• Easy to integrate legacy code because Spring Dependency Injection works with POJO (because of the two types of injection) – so it’s not intrusive.

Page 9: Training - Day 4

Use as much of Spring as needed

• Different ways to use Spring– Can be a full fledged application– Can be used modularly

• Major Pieces– Core– Context– DAO & ORM– AOP– Web & Web MVC

Page 10: Training - Day 4

Core

• Provides the Dependency Injection functionality which allows configuration and management of your bean container.

• This is the BeanFactory– No more need for programmatic singletons– Decouples configuration and the

specification of dependencies in code

Page 11: Training - Day 4

Context

• Provides access to beans in a framework-style manner– ApplicationContext– JNDI / EJB Support– Remoting– Etc.

Page 12: Training - Day 4

DAO and ORM

• DAO– Programmatic and Declarative transaction management of any

object (POJO)

– JDBC abstraction: vendor error codes, etc.

• ORM– Provides integration for popular O/R mapping frameworks like OJB

and Hibernate.

– Lots of hooks to take advantage of, for example, the declarative transaction management.

Page 13: Training - Day 4

AOP

• Aspect Oriented Programming

• AOP Alliance Compliant implementation of AOP.

• Provides method interceptors and pointcuts to cleanly separate code.

Page 14: Training - Day 4

Web and Web MVC

• Web– Web oriented application contexts.– Initialization via servlet listeners.– Multipart functionality.

• Web MVC– Spring’s version of Struts.

Page 15: Training - Day 4

Typical UIS Spring Usage Scenario

Spring middle-tier using a third-party web framework Note: We will use OJB rather than Hibernate.

Page 16: Training - Day 4

BeanFactory & ApplicationContext

• An ApplicationContext is a BeanFactory, and will be used most, if not all, of the time in UIS applications.

• ApplicationContext adds capabilities to the BeanFactory, most notibly J2EE specific functionality.

• You will need default empty constructors for setter injection.

Page 17: Training - Day 4

ExampleProgrammatic Instantiation of an Application Context

BeanFactoryLocator bfLocator = SingletonBeanFactoryLocator.getInstance("Spring.xml");BeanFactoryReference bfReference = bfLocator.useBeanFactory("appContext");BeanFactory factory = bfReference.getFactory();ApplicationContext appContext = (ApplicationContext) factory;

Spring.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans> <bean id="appContext" class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg> <list> <value>SpringDataSource.xml</value> <value>SpringBeans.xml</value> </list> </constructor-arg> </bean></beans>

Page 18: Training - Day 4

Example continued…

Partial Contents of SpringBeans.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<!-- User Service --> <bean id="trnUserService" class="edu.iu.uis.train.service.UserServiceImpl"> <property name="userDAO" ref="trnUserDAO" /> </bean>

<!-- User DAO --> <bean id="trnUserDAO" class="edu.iu.uis.train.dao.UserDAOOjbImpl"> <property name="jcdAlias" value="MYDB"/> </bean>

</beans>

Page 19: Training - Day 4

Defining a <bean/>

• A class name

• An id or name

• Singleton or prototype

• Bean properties

• Autowiring

• Lifecycle methods

Page 20: Training - Day 4

Class Name

• class=“package.classname”• Most likely, the name of the actual

implementing class of the object.– The preceding example

• Can also be the Factory that creates the object (this is a more rare case).– A few examples follow

Page 21: Training - Day 4

Factory examples

<bean id="exampleBean"

class="examples.ExampleBean2"

factory-method="createInstance"/>

or…<bean id="myFactoryBean" class="...“/>

<bean id="exampleBean"

factory-bean="myFactoryBean"

factory-method="createInstance"/>

Page 22: Training - Day 4

Id and Name

• id=“beanName” or name=“beanName”

• The id attribute is limited to the characters in a valid XML id

• If you need special characters, or want multiple ids, or aliases, you can use the name attribute (comma or semicolon separates multiple).

Page 23: Training - Day 4

Singleton or Prototype?

• singleton=“[true|false]”• Singleton will use one shared instance

of the bean for all requests (Default).• Prototype will result in the creation of a

new bean for each request. This is not used very often.– Spring does not handle the lifecycle of

prototype bean as it does singletons.

Page 24: Training - Day 4

Bean Properties

• Setter-injection– Recommended approach as constructor arguments can become

unwieldy

– Decouples code and enforces true JavaBeans

• Constructor-injection– Many ways to configure.

– Ensures beans are created in a valid state.

– Ensures beans have values if needed at object creation.

Page 25: Training - Day 4

Setter Properties Example

<bean id="exampleBean" class="examples.ExampleBean"> <property name="beanOne"> <ref bean="anotherExampleBean"/> </property> <property name="beanTwo"> <ref bean="yetAnotherBean"/> </property> <property name="integerProperty"> <value>1</value> </property> </bean>

<bean id="anotherExampleBean" class="examples.AnotherBean"/>

<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>

Page 26: Training - Day 4

Example continued…

public class ExampleBean { private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public void setBeanOne(AnotherBean beanOne) { this.beanOne = beanOne; } public void setBeanTwo(YetAnotherBean beanTwo) { this.beanTwo = beanTwo; } public void setIntegerProperty(int i) { this.i = i; } }

Page 27: Training - Day 4

Constructor Example

<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg> <ref bean="anotherExampleBean"/> </constructor-arg> <constructor-arg> <ref bean="yetAnotherBean"/> </constructor-arg> <constructor-arg type="int"> <value>1</value> </constructor-arg></bean>

<bean id="anotherExampleBean" class="examples.AnotherBean"/><bean id="yetAnotherBean" class="examples.YetAnotherBean"/>

Page 28: Training - Day 4

Example continued…

public class ExampleBean {

private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public ExampleBean(AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) { this.beanOne = anotherBean; this.beanTwo = yetAnotherBean; this.i = i; }}

Page 29: Training - Day 4

Factory/Constructor Example

<bean id="exampleBean" class="examples.ExampleBean" factory-method="createInstance"> <constructor-arg> <ref bean="anotherExampleBean"/> </constructor-arg> <constructor-arg> <ref bean="yetAnotherBean"/> </constructor-arg> <constructor-arg> <value>1</value> </constructor-arg></bean>

<bean id="anotherExampleBean" class="examples.AnotherBean"/><bean id="yetAnotherBean" class="examples.YetAnotherBean"/>

Page 30: Training - Day 4

Example continued…

public class ExampleBean { // a private constructor private ExampleBean(...) { ... } // a static factory method // the arguments to this method can be considered // the dependencies of the bean that is returned, // regardless of how those arguments are actually used. public static ExampleBean createInstance( AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) { ExampleBean example = new ExampleBean(...); // some other operations return example; }}

Page 31: Training - Day 4

Constructor Argument Resolution

• Happens by argument type.

• If no ambiguity, Spring can resolve for you via type matching (as in previous example).

• Otherwise, you can use argument indexing.

Page 32: Training - Day 4

Argument Indexing Example

<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg index="0"> <value>7500000</value> </constructor-arg> <constructor-arg index="1"> <value>42</value> </constructor-arg></bean>

Page 33: Training - Day 4

More on property “values”

• <value>…</value> – Used to set a textual value– Can be used for int, boolean, and String

• <null/>

• Lists, sets, maps and props– Allows for their equivalent data types to be

used.

Page 34: Training - Day 4

A few more examples…<bean id="moreComplexObject" class="example.ComplexObject"> <!-- results in a setPeople(java.util.Properties) call --> <property name="people"> <props> <prop key="HarryPotter">The magic property</prop> <prop key="JerrySeinfeld">The funny property</prop> </props> </property> <!-- results in a setSomeList(java.util.List) call --> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource"/> </list> </property> <!-- results in a setSomeMap(java.util.Map) call --> <property name="someMap"> <map> <entry> <key><value>yup an entry</value></key> <value>just some string</value> </entry> </map> </property> <!-- results in a setSomeSet(java.util.Set) call --> <property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource"/> </set> </property></bean>

Page 35: Training - Day 4

<idref> Attribute

• <idref bean=“…”/>– Same a id– Benefit is that Spring can validate it.

• <idref local=“…”/> – When bean is in the same XML config file.– Similar to above, but the XML parser can

validate at document parse time.

Page 36: Training - Day 4

<ref> Attribute

• Allows a property to use another bean reference as its value– <ref bean="someBean"/>

• Can also take advantage of local• Shortcuts

– <property name="myProperty" value="hello"/>– <constructor-arg value="hello"/>– <entry key="myKey" value="hello"/>

Page 37: Training - Day 4

Exercise: Bean wiring

• Create a movie DAO bean in the SpringBeans.xml file and inject it into the movie service.

Page 38: Training - Day 4

Autowiring

• Spring Magic!

• Spring will try to figure out what dependencies should be injected into your beans.

• Can not have ambiguities.

• Not recommended.

Page 39: Training - Day 4

Lifecycle Attributes

• < bean … init-method=“…”/> – Specifies a method to call after a bean is

created.

• <bean … destroy-method=“…”/>– Specifies a method to call after a bean is

about to be destroyed (a callback).

Page 40: Training - Day 4

The Application Context

• More framework oriented

• Recommended over a plain Bean Factory

• Provides:– Access to I18N style messages– Access to resources– Event propagation– Loading of multiple contexts

Page 41: Training - Day 4

Creating an Application Context

• Add a listener to web.xml to start Spring

<listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class></listener>

• The listener can be configured with a context parameter

<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/classes/SpringBeans.xml /WEB-INF/classes/SpringDataSource.xml </param-value></context-param>

Page 42: Training - Day 4

Injecting your Struts Actions• In your struts-config.xml

<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"/>

• You also need to define your Action injection in /WEB-INF/action-servlet.xml

<beans> <bean name="/BanUser" class="edu.iu.uis.train.web.BanUserAction"> <property name="userService" ref="trnUserService" /> </bean> <bean name="/Admin" class="edu.iu.uis.train.web.AdminAction"> <property name="userService" ref="trnUserService" /> </bean></beans>

Page 43: Training - Day 4

Injecting Actions Continued…

- Finally, delegate Struts actions to Spring proxies

<action

path=”/Admin"

type="org.springframework.web.struts.DelegatingActionProxy"

name=”AdminForm" parameter="methodToCall">

<forward name="success" path="/WEB-INF/jsp/admin/Admin.jsp" />

</action>

Page 44: Training - Day 4

Exercise: Injecting Struts

• Modify struts-config.xml to use Spring

• Update action-servlet.xml with proper classes and injected services.

Page 45: Training - Day 4

A Spring Service Locator

• Another approach to obtaining spring services in Actions or other services

• Allows “singleton-like” access to services by a constant name• Calls the BeanFactory to retrieve the bean behind the scenes• Couples code a bit more than injection, but is sometimes easier

to use– Need to keep the constants up to date in the locator class file– Need to recompile code when additions are needed

Page 46: Training - Day 4

Examplepublic class SpringServiceLocator { private static ApplicationContext appContext; private static boolean initializationBegan = false;

public static final String USER_SRV = "trnUserService"; public static final String PROJECT_SRV = "trnProjectService";

public static Object getService(String serviceName) { if (appContext == null && !initializationBegan) { initializationBegan = true; initializeAppContexts("Spring.xml"); } else if (appContext == null && initializationBegan) { throw new RuntimeException("Spring not initialized properly."); } return appContext.getBean(serviceName); }

protected static void initializeAppContexts(String rootContextFile) { BeanFactoryLocator bfLocator = SingletonBeanFactoryLocator.getInstance(rootContextFile); BeanFactoryReference bfReference = bfLocator.useBeanFactory("appContext"); BeanFactory factory = bfReference.getFactory(); appContext = (ApplicationContext) factory; }

Page 47: Training - Day 4

Example continued…

public static UserService getUserService() { return (UserService) getService(USER_SRV); }

public static ProjectService getProjectService() { return (ProjectService) getService(PROJECT_SRV); } public static void setAppContext(ApplicationContext newAppContext) { appContext = newAppContext; } public static ApplicationContext getAppContext() { return appContext; }

public static void close() { if (appContext instanceof ConfigurableApplicationContext) {

((ConfigurableApplicationContext) appContext).close(); }}

}

Page 48: Training - Day 4

Using the locator

User user = SpringServiceLocator.getUserService().

findUserByUsername(role.getUser().getUsername());

As opposed to…

User user = getUserService().findUserByUsername(

role.getUser().getUsername());

Page 49: Training - Day 4

Spring AOP

• Aspect Oriented Programming compliments OOP.• Breaks programs down into aspects and concerns,

often times called cross-cutting concerns.• In Spring, AOP is used for:

– Declarative enterprise services– Implementing custom aspects

• You choose how much AOP you want to use

Page 50: Training - Day 4

AOP Concepts

• AOP terminology is confusing and unintuitive.

• The Spring Framework did not want to change this terminology, which could have made it more confusing, but rather stuck with the generic AOP terms.

Page 51: Training - Day 4

Aspects

• A way to modularize something, a concern, that may “cut across” multiple objects.

• Famous example: Declarative transaction management (EJB does this as well).

• Implemented as an advisor or an interceptor.

Page 52: Training - Day 4

Jointpoints

• A point during program execution, such as a method invocation or an exception.

• In Spring, a joinpoint is always a method invocation.

Page 53: Training - Day 4

Advice

• The action taken at a particular joinpoint.

• There are different types of advice:– Around– Before– Throws

• Spring uses an interceptor (or chain) around the joinpoint.

Page 54: Training - Day 4

Pointcut

• A set of joinpoints specifying when an advice should fire.

• An AOP framework must allow the developer to specify pointcuts, for example, using regular expressions.

Page 55: Training - Day 4

Introduction

• Adding methods or fields to an advised class.

• Spring allows you to introduce new interfaces to any advised object.

• Example: use Spring to make certain objects setter methods “locked” by making them implement a Lockable interface.

Page 56: Training - Day 4

Target Object

• A target is the object that contains a joinpoint.

• Also known as:– Advised– Proxied

Page 57: Training - Day 4

AOP proxy

• Any object created by the AOP framework, including advice.

• In Spring proxies are either:– JDK dynamic proxies – need interface– CGLIB proxies – don’t need interface

Page 58: Training - Day 4

Weaving

• Assembling aspects to create an advised object.

• Can be done at compile time or at runtime.

• Spring performs weaving at runtime, whereas an AOP compiler, like AspectJ, is needed for compile time weaving.

Page 59: Training - Day 4

Advice types

• Around– Most powerful– Surrounds a method invocation (allowing for work to be

done before and after call).– Responsible for whether to proceed to the joinpoint, or return

their own value.

• Before– Executes before joinpoint.– Has no power to prevent the joinpoint.

Page 60: Training - Day 4

A few more types…

• Throws– Executed if the method throws an

exception.– Provides strongly typed throws advice.

• After– Executed after a joinpoint executes

normally.

Page 61: Training - Day 4

More info…

• See the Spring Documentation chapter on AOP for more complex examples of Aspect Oriented Programming using the Spring Framework.– http://static.springframework.org/spring/

docs/1.2.x/reference/aop.html

Page 62: Training - Day 4

Last words on AOP

• The biggest benefit that we get from AOP is declarative transaction management– Similar to EJB transactions– More later

• One last example: Custom AOP Logging– Logs when you arrive in a method– Logs when you exit a method– Calculates the time spent in a method

Page 63: Training - Day 4

Logging Interceptorimport org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import org.apache.log4j.Logger;

public class LoggingInterceptor implements MethodInterceptor {

private static final Logger LOG = Logger.getLogger(LoggingInterceptor.class);

public Object invoke(MethodInvocation methodInvocation) throws Throwable { String methodName = methodInvocation.getMethod().getDeclaringClass() + "::" + methodInvocation.getMethod().getName();

// log here when you enter // save the time in a temp variable

// proceed with the method call, BUT ensure that you will get back after // proceed(), even if proceed fails return methodInvocation.proceed();

// log now that you done // calculate the time it took and log it}

}

Page 64: Training - Day 4

Exercise: A little AOP Magic

• See the logging interceptor bean in SpringBeans.xml for the LoggingInterceptor.java class. It logs all beans that are a DAO or a Service (actually all beans that start with trn).

• Finish the LoggingInterceptor.java class– Logs when you arrive in a method– Logs when you exit a method– Calculates the time spent in a method and log it

Page 65: Training - Day 4

Spring and OJB

• If you are going to use OJB in a project, Spring should be a requirement.

• This is true even if you do not use any other feature in Spring other than the O/R mapping support.

• Biggest benefits:– Declarative transaction management– DAO Support & Connection management

Page 66: Training - Day 4

Declarative Transaction Management

• One of the big reasons people use EJB• The opposite being Programmatic Transaction

Management, which can also be done in Spring• Done with AOP• Is very configurable, though we will only cover a one-

size fits all configuration, which we recommend until tuning is needed

Page 67: Training - Day 4

Spring Configuration<!-- OJB Support --><bean id="ojbConfigurer" class="org.springframework.orm.ojb.support.LocalOjbConfigurer" />

<!–- OJB Transaction Manager --><bean id="transactionManager"

class="org.springframework.orm.ojb.PersistenceBrokerTransactionManager"> <property name="jcdAlias" value="MYDB"/></bean>

<!-- Transaction Support --><bean id="matchAllWithPropReq"

class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource"> <property name="transactionAttribute" value="PROPAGATION_REQUIRED" /></bean>

<!-- An Interceptor for matching with PROPAGATION_REQUIRED --><bean id="matchAllTxInterceptor"

class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager" ref="transactionManager" /> <property name="transactionAttributeSource" ref="matchAllWithPropReq" /></bean>

Page 68: Training - Day 4

Spring Config Continued…

<!-- Auto Proxy for Transaction Management --><bean id="transactionAutoProxy"

class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="interceptorNames"> <list> <idref local="matchAllTxInterceptor" /> </list> </property> <property name="beanNames"> <list> <value>trn*Service</value> </list> </property></bean>

Page 69: Training - Day 4

DAO Support

• Extend the Spring Helper Class org.springframework.orm.ojb.support.PersistenceBrokerDaoSupport

– Need to inject a jcdAlias (see project for example)

• Provides a PersistenceBrokerTemplate• Ensures PersistenceBrokers are opened and

closed correctly• Code automatically participates in

transactions• Thread-safe so can be instance variables

Page 70: Training - Day 4

Recall: The OJB w/o Spring Way

public void saveUser(User user) { PersistenceBroker broker = PersistenceBrokerFactory.defaultPersistenceBroker(); try { broker.beginTransaction(); broker.store(user); broker.commitTransaction(); } catch (Exception e) { broker.abortTransaction(); LOG.error("error retrieving stats", e); } finally { if (!broker.isClosed()) broker.close(); }}

Page 71: Training - Day 4

OJB with Spring

public class UserDAOOjbImpl extends PersistenceBrokerDaoSupport implements UserDAO {

public void saveUser(User user) { getPersistenceBrokerTemplate().store(user); }

// lots of methods removed}

Page 72: Training - Day 4

Longer Examplepublic class UserDAOOjbImpl extends PersistenceBrokerDaoSupport implements UserDAO {

public User findUser(String personId) { LOG.debug("Find user: "+personId); Criteria criteria = new Criteria(); criteria.addEqualTo("personId", personId); return (User) getPersistenceBrokerTemplate(). getObjectByQuery(new QueryByCriteria(User.class, criteria)); }

public void saveUser(User user) { getPersistenceBrokerTemplate().store(user); }

public boolean isUserBanned(String personId) { Criteria crit = new Criteria(); crit.addEqualTo("banPersonId", personId); long count = getPersistenceBrokerTemplate().getCount(new QueryByCriteria(BanUser.class, crit)); if (count > 0) { return true; } return false; }

public List findAllBanUsers() { return (List) getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(BanUser.class)); }

public void deleteBanUser(BanUser banUser) { getPersistenceBrokerTemplate().delete(banUser); } }

Page 73: Training - Day 4

Exercise: Updating your DAO

• Modify your MovieDAOImpl to use the new Spring/OJB method

Page 74: Training - Day 4

Using Spring to help Test

• By using Spring, your classes should be much easier to test because Spring is unobtrusive.– Should not depend on the container as it

would if using something like EJB.– Since objects are injected via setters,

everything can be set in a unit test… somewhat magically.

Page 75: Training - Day 4

org.springframework.test• Context caching

– Speeds up test run time – don’t have to load the context files for each test.

• Dependency injection for test classes– Will auto-inject for each setter in a test.

• Appropriate test transaction management– Runs tests in a transaction that is rolled back after the test runs,

resulting in “untouched” database.• Using inherited instance variables

– applicationContext: explicit bean lookup– jdbcTemplate: runs in same transaction (useful to query)

• Use the SIT Helper– Provides access to an OJB Persistence Broker (better for querying

because the transaction doesn’t need to be flushed and you can use standard OJB criteria queries).

– Common place to set up your test spring configuration.

Page 76: Training - Day 4

Examplepublic class ProjectServiceImplTest extends PersistenceBrokerAbstractTransactionalDataSourceSpringContextTests {

private ProjectService projectService; private UserService userService; public UserService getUserService() { return userService; }

public void setUserService(UserService userService) { this.userService = userService; }

public ProjectService getProjectService() { return projectService; }

public void setProjectService(ProjectService projectService) { this.projectService = projectService; }

Page 77: Training - Day 4

Example continued… public void testSaveProject() { String projectName = "The jUnit Test Project"; String personId = "12345678900"; String username = "The jUnit Test Username"; String role = "The jUnit Test Role"; User user = new User(); user.setPersonId(personId); user.setUsername(username); getUserService().saveUser(user); Description description = new Description(); description.setDescription("This is a test.");

Project project = new Project(); project.setActive(true); project.setCreateDate(new Timestamp((new Date()).getTime())); project.setDescription(description); project.setDueDate(new Timestamp((new Date()).getTime())); project.setProjectName(projectName); description.setProject(project); getProjectService().saveProject(project);

Page 78: Training - Day 4

Example concluded RoleProjectUser roleProjectUser = new RoleProjectUser(); roleProjectUser.setRole(role); roleProjectUser.setProject(project); roleProjectUser.setUser(user); getProjectService().saveRole(roleProjectUser); Criteria criteria = new Criteria(); criteria.addLike("projectName", projectName); int count = getPersistenceBroker().getCount(new QueryByCriteria(Project.class, criteria)); assertEquals("Project [" + projectName + "] did not save properly.", count, 1); criteria = new Criteria(); criteria.addLike("role", role); count = getPersistenceBroker().getCount(new QueryByCriteria(RoleProjectUser.class, criteria)); assertEquals("Role [" + role + "] did not save properly.", count, 1); }

}

Page 79: Training - Day 4

References

• Spring Framework Documentation– http://static.springframework.org/spring/doc

s/1.2.x/reference/index.html

• Martin Fowler’s Dependency Injection– http://martinfowler.com/articles/injection.html


Recommended