Spring/Testing Training
description
Transcript of Spring/Testing Training
![Page 1: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/1.jpg)
Spring/Testing Training
Jay Sissom
![Page 2: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/2.jpg)
Topics
• Java Interfaces
• Service Oriented Architecture
• Spring
• Testing with junit
![Page 3: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/3.jpg)
Exercise 1
• Check out FPS/TRAINING/INTERFACE1• Open edu.iu.uis.Main.java• Create instances for each pet• Put them all in a collection• Iterate through the collection and print
each pet’s name and make it speak (Don’t modify Cat & Dog classes)
• Hint: instanceof
![Page 4: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/4.jpg)
Java Interface
• An Interface is a special Java class that defines behavior but doesn’t implement the behavior
• It defines what another object will do, not how it does it
• It is used to declare methods that an object must implement
• Use of interfaces allows objects to be dependant on behavior, but not specific object instances
![Page 5: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/5.jpg)
Java Interface
• By using Interfaces, you don’t hard code which object must provide a service for you
• The object providing the service can be any object that implements the required interface
![Page 6: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/6.jpg)
Java Interface
• An example is Collection. A Collection must allow you to: Add items Clear all items Remove items Get the size Get an iterator to all members (among other things)
• http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html
![Page 7: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/7.jpg)
Java Interface
• Many objects implement the Collection interface ArrayList Vector LinkedList And the list goes on….
• http://java.sun.com/j2se/1.4.2/docs/api/java/util/LinkedList.html
![Page 8: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/8.jpg)
Java Interface
• You can create your own Java interface:
public interface Worker {
}
public void doWork();
public Collection getData();
![Page 9: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/9.jpg)
Java Interface
• Any number of classes can implement your interface:
public class MyWork implements Worker {
return new ArrayList(); }
// Pretend I’m working }}
public void doWork() { public Collection getData() {
![Page 10: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/10.jpg)
Java Interface
• Your interface can be used in place of an object name:
public Worker getMyWorker() …
public void doStuff(Worker w) …
• When doing this, your code isn’t dependent on a single implementation of Worker. Any implementation will do.
![Page 11: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/11.jpg)
Exercise 2
• Use interface1 project (or check out FPS/TRAINING/INTERFACE1ANSWER if you didn’t finish Exercise 1)
• Create a Pet interface that defines the common functionality in Cat & Dog
• Change Cat & Dog to implement this interface• Change Main to use the interface instead of
specific instances• Extra Credit: Add a Parrot object and use it
![Page 12: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/12.jpg)
Inheritance
• Inheritance is a parent child relationship between classes
• Children inherit a parent’s functionalityAnimal
public String speak();
public String getName();
Dog
![Page 13: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/13.jpg)
Inheritance
• Inheritence implies that all children will have the functionality defined in the parent
• You have to be very careful when designing inheritance
Animal public String speak();
public String getName();
AntDonGrinstead
![Page 14: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/14.jpg)
Solution with Interfaces
• Using interfaces in this case would be more accurate
Named <<interface>>
public String getName();
AntDonGrinstead
Speaker <<interface>> public String speak();
![Page 15: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/15.jpg)
Inheritance/Interfaces
Issue Interface Inheritance
How Many per class Any number One parent per child
Inherit method signatures
Yes Yes
Inherit functionality No Yes
![Page 16: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/16.jpg)
Interface Conclusion
• A Java Interface defines what implementing objects do, not how they do it
• Using interfaces will decouple your code from dependant objects. This will make it easier to maintain the code in the future
![Page 17: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/17.jpg)
Exercise 3
• Check out FPS/TRAINING/INTERFACE3
• Create an implementation of OrderCalculator that calculates sales tax as 6% if from Indiana, 0 if from another state
• Shipping is $20 if another state, $15 if Indiana• Change Main to use this interface• Modify the interface to add this method: public double
getOrderTotal(Order o); that returns the total of the order with tax & shipping
• Modify Main to use this method• Make sure you modify both implementations to implement
this interface
![Page 18: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/18.jpg)
Interfaces Pt 2
• We still had to put the name of the implementation class in our last example
• If we used that throughout our application, we’d need to change it everywhere
• This is still a problem
![Page 19: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/19.jpg)
Interfaces Pt 2
• A solution is to create a new class that has a method to return the implementation we want
• public OrderCalculator getInstance();
• This allows us to specify our implementation once for the whole app
• This is called the Factory pattern
![Page 20: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/20.jpg)
Exercise 4
• Use interface3 project
• Create OrderCalculatorFactory class that has one method public OrderCalculator getInstance();
• This method should return an instance of your order calculator class
• Change Main to use the factory
![Page 21: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/21.jpg)
Interfaces Pt 3
• Now we specified the implementation class in one place in our app
• This is better, but it would be best if the implementation class name wasn’t in Java code
• We can put this class name in a properties file. The factory can read the properties file to determine the class name
• Now the class name isn’t in compiled Java code. See FPS/TRAINING/INTERFACE4ANSWER2 for an example
![Page 22: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/22.jpg)
Interfaces Pt 3
• Now we need a Factory, Interface and properties file for each class
• This is too much work!• We could build a Factory framework so we
need one factory and properties file for our app
• Or we could use an open source framework called Spring
![Page 23: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/23.jpg)
Spring
• Spring Mission Statement J2EE should be easier to use It's best to program to interfaces, rather than classes. Spring
reduces the complexity cost of using interfaces to zero. JavaBeans offer a great way of configuring applications. OO design is more important than any implementation
technology, such as J2EE. Checked exceptions are overused in Java. A framework
shouldn't force you to catch exceptions you're unlikely to be able to recover from.
Testability is essential, and a framework such as Spring should help make your code easier to test.
![Page 24: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/24.jpg)
Spring
• Spring can replace our factory classes and properties file
• All classes can be defined to spring and we don’t need to write custom factories
• See FPS/TRAINING/SPRING1ANSWER
![Page 25: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/25.jpg)
Spring
• Objects are defined as “beans” in a spring xml file:
<bean id="OrderCalculator" class="edu.iu.uis.NewOrderCalculator"/>
• The object is accessed via the beanFactory:
OrderCalculator oc = (OrderCalculator)factory.getBean("OrderCalculator");
•
![Page 26: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/26.jpg)
Execise 5
• Check out FPS/TRAINING/SPRING2
• Refactor NewOrderCalculator to use MemorySalesTax object
• Use Spring as the factory to find the object (the beanFactory is provided for you)
![Page 27: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/27.jpg)
Dependencies
• OrderCalculator depends on the SalesTax object to do its work
• Main depends on OrderCalculator
• When an object needs another to do its work, that is a Dependency
• Spring helps satisfy dependencies
• Using Interfaces makes it flexible
![Page 28: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/28.jpg)
Dependencies
• To satisfy dependencies in our code we can: Create the dependent objects using new Use a Factory to get them Have something external to the object create
them for us
• The last option is called Dependency Injection or Inversion of Control
![Page 29: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/29.jpg)
Inversion of Control
• There are three types of IoC Constructor Based Setter Based Getter Based
![Page 30: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/30.jpg)
Constructor Based IoC
• All dependent objects are passed on the constructor
• All dependancies are satisfied when the object is created
• If you have lots of dependancies, you have a huge constructor
![Page 31: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/31.jpg)
Setter Based IoC
• All dependent objects have a setXXX method
• The factory will call these for each dependent object
• Good when there are lots of dependencies
• This documents the dependencies better than Constructor based IoC
![Page 32: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/32.jpg)
Getter Based IoC
• Each object needs access to a container
• The object calls get methods on the container to get dependencies
• This is the way we have been using Spring
• Our code now has a dependency on Spring which may be a problem
![Page 33: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/33.jpg)
Spring IoC
• Spring supports all three IoC types Getter - using BeanFactory Setter - using bean.xml Constructor - using bean.xml
• The most popular is Setter based IoC
• This is the recommended way to handle dependencies
![Page 34: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/34.jpg)
Spring Setter IoC
• Dependencies are mapped in the bean xml file Update the xml to show the dependency Create a setter method in the bean The setter method saves the dependency to
use it in the future
![Page 35: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/35.jpg)
Spring Setter IoC
• Update the xml to show the dependency
<bean id="OrderCalculator" class="edu.iu.uis.NewOrderCalculator">
<property name="salesTax"> <ref bean="SalesTax"/> </property> </bean>
![Page 36: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/36.jpg)
Spring Setter IoC
• Create a setter method in the bean & save the dependency to use when necessary
private SalesTax salesTax;
public void setSalesTax(SalesTax st) {
salesTax = st;
}
![Page 37: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/37.jpg)
Exercise 6
• Modify the spring2 project to use setter injection in OrderCalculator
• Hint: You can remove the BeanFactory code in NewOrderCalculator because it isn’t necessary anymore
FPS/TRAINING/SPRING2ANSWER2
![Page 38: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/38.jpg)
Spring with Struts
• There are a few steps required to get Spring working with Struts Starting up Spring Location of bean xml Spring/Struts integration
![Page 39: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/39.jpg)
Starting up Spring
• Spring starts up with a servlet listener
• This code needs to be in web.xml
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
![Page 40: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/40.jpg)
Location of bean xml
• Spring looks for beans in /WEB-INF/applicationContext.xml
• This can be changed by adding the following in web.xml
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value></context-param>
![Page 41: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/41.jpg)
Spring/Struts integration
• Spring can handle IoC in Struts Actions
• Define dependencies in xml file
• Spring calls setter methods in Struts Actions
![Page 42: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/42.jpg)
Spring/Struts integration
• Define Struts plugin in struts-config.xml
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"/>
• Spring looks in /WEB-INF/action-servlet.xml for Struts action bean definitions
• Note: action is the name of the Struts Servlet in web.xml
![Page 43: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/43.jpg)
Spring/Struts integration
• The type of each action in struts-config.xml should be org.springframework.web.struts.DelegatingActionProxy
• The dependencies and actual type should be defined in action-servlet.xml
<bean name="/path" class="edu.iu.uis.pdp.action.ChannelAction"> <property name="userService"><ref bean="pdpUserService"/></property></bean>
• Note: /path needs to match path in <action-mappings> in struts-config.xml
![Page 44: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/44.jpg)
Spring/Struts integration
• Struts Actions are defined in action-servlet.xml
• Other beans are defined in applicationContext.xml
• Struts actions can access beans defined in applicationContext.xml
• applicationContext.xml beans can’t access Struts actions
![Page 45: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/45.jpg)
Exercise 7
• Check out FPS/TRAINING/STRUTS1
• Setup Spring for the application Put beans in applicationContext.xml & action-
servlet.xml Put setter methods in beans Update struts-config.xml for Spring Update web.xml for Spring
![Page 46: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/46.jpg)
Application Testing
• Unit Testing – Test each object as it is written
• Functional Testing – Test each use case to make sure it works properly
• Usability Testing – Test the app to make sure users understand it
• Load Testing – Make sure the application will perform properly under a load
![Page 47: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/47.jpg)
jUnit
• Unit Tests are a series of tests that verify each component of your application
• jUnit is a framework to help standardize these tests
• jUnit can help automate tests so it is easy to see if a component works
• Open Source Framework
• Integrated into Eclipse and ant
![Page 48: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/48.jpg)
Why Unit Test?
• Find bugs soon after code is written
• Save other team members’ time
• Prove that finished code works
• Make future maintenance easier
• Example of how to use code
![Page 49: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/49.jpg)
Unit testing goals
• Each class has tests for all public methods• Tests not only test successes, but also test
failures• Tests are organized so they are easy to run• Tests are run often• Each test is completely independent of other
tests• Each time a bug is found, write an additional test
to check for that bug, then fix the bug
![Page 50: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/50.jpg)
jUnit Concepts
• TestCase – a series of related tests All the tests for an object All the tests for a method
• TestSuite – a series of related test cases All tests for a package All tests for a use case All tests for an application
![Page 51: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/51.jpg)
jUnit Concepts
• TestRunner – jUnit code that runs tests Command line Swing Eclipse
![Page 52: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/52.jpg)
jUnit Addons
• Dbunit – code to initialize a database to a known state before testing
• Struts test case – Test Struts specific code using mock objects
• Cactus – Test HTTP applications using mock objects
• HttpUnit – Test HTTP applications based on an embedded servlet container
![Page 53: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/53.jpg)
Writing jUnit tests
• Subclass junit.framework.TestCase
• Create a constructor with a single String parameter. Call super(string) in this constructor
• Write tests in methods that return void and start with test as their name
• Call fail, assertX in tests as necessary
![Page 54: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/54.jpg)
Writing jUnit tests
• protected void setUp() is called before each test method
• protected void tearDown() is called after each test method
• These can be used to setup and cleanup the environment required for each test
![Page 55: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/55.jpg)
Test success/failure
• assertX methods test for the correct values. Examples: assertTrue/assertFalse assertNull/assertNotNull assertEquals
• Fail() method stops the test and marks it as a failure
• Throwing an uncaught exception marks the test as a failure
![Page 56: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/56.jpg)
Test success/failure
• The assertEquals method takes the following arguments String = a message that is printed if the
assertion fails Expected value = the value expected Test value = the value to test
• Double & Float comparisons take a 4th argument - a precision range
![Page 57: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/57.jpg)
Example test
/** * Test searching for someone that doesn't exist **/public void testGetPerson1() throws Exception{ BusinessLogic bl = (BusinessLogic)beanFactory.getBean(“BusinessLogic”); Person p = bli.getPerson("Unknown"); assertNull("Unknown person should be null",p);}
![Page 58: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/58.jpg)
Exercise 8
• Check out FPS/TRAINING/JUNIT1
• Create a series of junit tests for the UsaTax2004Calculator object
• See http://www.bankrate.com/brm/itax/2004taxrates.asp for the official tax rates
• There is at least one bug in the object
![Page 59: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/59.jpg)
Best Practices
• Make each test method only test one feature• Test for success and failure• Build a test suite that runs all your tests• When a bug is found, write a test to find the bug,
then fix the bug• Write tests that don’t depend on external
systems (database or GDS)
![Page 60: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/60.jpg)
Best Practices
• Tests shouldn’t be dependent on other tests
• Don’t test things that can’t break
• Put tests in their own package
• Read the jUnit FAQ• http://junit.sourceforge.net/doc/faq/faq.htm
![Page 61: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/61.jpg)
jUnit Summary
• jUnit helps you create higher quality software
• Time spent by writing tests will be recovered many times over during future maintenance
![Page 62: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/62.jpg)
Test Driven Development
• TDD is a standard for Kuali development and may be a future standard for UIS
• This completely changes the way you develop code
• Tests are developed before production code
![Page 63: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/63.jpg)
Test Driven Development
• When using TDD, here is how to build functionality: Write a single test Compile it. It shouldn't compile, because you haven't written the
implementation code it calls Implement just enough code to get the test to compile Run the test and see it fail Implement just enough code to get the test to pass Run the test and see it pass Refactor for clarity and "once and only once" Repeat
http://xprogramming.com/xpmag/testFirstGuidelines.htmhttp://www.differentpla.net/node/view/58
![Page 64: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/64.jpg)
Test Driven Development
• Test Driven Development (a.k.a. Test-first design ) is one of the core programming practices of XP. Many of us have learned over the years the value of writing automated tests for our code. Many of us have also learned the difficulty of writing tests after code is already in place. Test-first design takes a different, extreme approach to ensure that we test all code, all the time.
• The practice of test-first design begets a changed mindset: we write tests not as an afterthought to ensure our code works, but instead as just part of the everyday, every-minute way of building software. Instead of writing our detailed design specifications on paper, we write them in code. Instead of first striving to perfectly design a system on paper, we use tests to guide our design. Instead of coding for hours at a stretch, only to find our planning went awry, we use test-first design to pace ourselves, always assuring that we are moving forward correctly with each passing minute.
![Page 65: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/65.jpg)
The steps
• Write a test that specifies a tiny bit of functionality
• Ensure the test fails (you haven't built the functionality yet!)
• Write only the code necessary to make the test pass
• Refactor the code, ensuring that it has the simplest design possible for the functionality built to date
![Page 66: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/66.jpg)
The rules
• Test everything that can possibly break
• Tests come first
• All tests run at 100% all the time
![Page 67: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/67.jpg)
The benefits
• Code is written so that modules are testable in isolation. Code written without tests in mind is often highly coupled, a big hint that you have a poor object-oriented design. If you have to write tests first, you'll devise ways of minimizing dependencies in your system in order to write your tests.
• The tests act as system-level documentation. They are the first client of your classes; they show how the developer intended for the class to be used.
![Page 68: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/68.jpg)
The benefits
• The system has automated tests by definition. As your system grows, running full regression tests manually will ultimately take outrageous amounts of time.
• Development is paced. We specify tiny bits of functionality in our tests, then write a small amount of code to fulfill that specification. Rinse, repeat. Tiny means seconds to a few minutes. The code base progresses forward at a relatively constant rate in terms of the functionality supported.
![Page 69: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/69.jpg)
Example
• Roman Number converter
![Page 70: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/70.jpg)
Quick Review
• Using Java interfaces makes our code more flexible
• Spring is a Factory that lets us change implementations of objects without recompiling
• jUnit is a framework to help developers test objects
• TDD is really great and we’re all going to love it We WILL use it on the next exercise!
![Page 71: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/71.jpg)
Exercise 8
• Create a Bowling Score Calculator
• Use Test Driven Development
![Page 72: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/72.jpg)
Data Access With Spring
• Spring provides services to make writing database code easier Automatic connection handling Simplified data access code using templates Declarative transaction management
![Page 73: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/73.jpg)
Auto Connection Handling
• Spring can manage your database connection for you
• It is NOT a connection pool, it uses the container’s connection pool
• It will retrieve connections when you need them and close them when you are done
• This means less code for you to write
![Page 74: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/74.jpg)
Template
• Spring provides templates for Hibernate, iBatis, JDBC, OJB and JDO
• A template provides Connection management Exception translation
![Page 75: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/75.jpg)
Template
• DAO objects can use this template by extending a DaoSupport class
• For OJB, it is PersistenceBrokerDaoSupport
• Call getPersistenceBrokerTemplate() in code to access the template
![Page 76: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/76.jpg)
Template
• Methods available store() - store a persistent object delete() - delete a persistent object getCollectionByQuery() - get a collection getObjectByQuery() - get an object There are others
• Usually updating the database requires a one line method:
public store(Object o) { getPersistenceBrokerTemplate().store(o);
}
![Page 77: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/77.jpg)
Example
• Sales Tax Application
• FPS/TRAINING/DAO1
![Page 78: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/78.jpg)
Exercise 9
• Check out FPS/TRAINING/DAO2
• Write an OJB DAO according to the interface StateDao
• Make sure to update the applicationContext file
• Run the web app to see if it worked
• http://localhost:8080/dao2/state.do
![Page 79: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/79.jpg)
Testing with Mock Objects
• A Mock object is like an acting double• We use Java interfaces so we can swap
out functionality• This allows us to swap out dependent
objects with Mock objects for testing• With mock objects, we can test the
business logic tier without talking to other systems
![Page 80: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/80.jpg)
Why Mock Objects
• The real object has nondeterministic behavior
• The real object is difficult to set up
• The real object has behavior that is hard to trigger
• The real object is slow
• Others…
Pragmatic Unit Testing
![Page 81: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/81.jpg)
Mock Objects
• There are Mock object frameworks jMock EasyMock MockCreator Probably others
• OR You can create your own Mock objects
![Page 82: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/82.jpg)
Mock Object
• A Mock object can be a simple Java object that implements the correct interface
• A DAO Mock Object can implement the correct interface, then each method is implemented as simply as possible
• You can implement the methods as needed by your test cases
![Page 83: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/83.jpg)
Mock Objects
• Insert some really cool exercise here…
![Page 84: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/84.jpg)
Declarative Transactions
• Spring can coordinate transactions for you in one of two ways Programatic - in Java code Declarative - in the applicationContext xml
• Using declarative transaction means less code to maintain
![Page 85: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/85.jpg)
Declarative Transactions
<bean id="pdpReferenceServiceImpl" class="edu.iu.uis.pdp.service.impl.ReferenceServiceImpl"> <property name="referenceDao"><ref local="pdpReferenceDao"/></property></bean>
<bean id="pdpReferenceService” class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref bean="TransactionManager"/></property> <property name="target"><ref bean="pdpReferenceServiceImpl"/></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property></bean>
Example from applicationContext.xml
![Page 86: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/86.jpg)
Declarative Transactions
<bean id="pdpReferenceServiceImpl" class="edu.iu.uis.pdp.service.impl.ReferenceServiceImpl"> <property name="referenceDao"><ref local="pdpReferenceDao"/></property></bean>
<bean id="pdpReferenceService” class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref bean="TransactionManager"/></property> <property name="target"><ref bean="pdpReferenceServiceImpl"/></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property></bean>
Example from applicationContext.xml
Class we write
![Page 87: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/87.jpg)
Declarative Transactions
<bean id="pdpReferenceServiceImpl" class="edu.iu.uis.pdp.service.impl.ReferenceServiceImpl"> <property name="referenceDao"><ref local="pdpReferenceDao"/></property></bean>
<bean id="pdpReferenceService” class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref bean="TransactionManager"/></property> <property name="target"><ref bean="pdpReferenceServiceImpl"/></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property></bean>
Example from applicationContext.xml
It calls DAOs for data access
![Page 88: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/88.jpg)
Declarative Transactions
<bean id="pdpReferenceServiceImpl" class="edu.iu.uis.pdp.service.impl.ReferenceServiceImpl"> <property name="referenceDao"><ref local="pdpReferenceDao"/></property></bean>
<bean id="pdpReferenceService” class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref bean="TransactionManager"/></property> <property name="target"><ref bean="pdpReferenceServiceImpl"/></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property></bean>
Example from applicationContext.xml
Other beans access our code via this id
![Page 89: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/89.jpg)
Declarative Transactions
<bean id="pdpReferenceServiceImpl" class="edu.iu.uis.pdp.service.impl.ReferenceServiceImpl"> <property name="referenceDao"><ref local="pdpReferenceDao"/></property></bean>
<bean id="pdpReferenceService” class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref bean="TransactionManager"/></property> <property name="target"><ref bean="pdpReferenceServiceImpl"/></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property></bean>
Example from applicationContext.xml
Spring provides a proxy class that handles transactions
![Page 90: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/90.jpg)
Declarative Transactions
<bean id="pdpReferenceServiceImpl" class="edu.iu.uis.pdp.service.impl.ReferenceServiceImpl"> <property name="referenceDao"><ref local="pdpReferenceDao"/></property></bean>
<bean id="pdpReferenceService” class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref bean="TransactionManager"/></property> <property name="target"><ref bean="pdpReferenceServiceImpl"/></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property></bean>
Example from applicationContext.xml
Spring’s proxy class calls our real class
![Page 91: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/91.jpg)
Declarative Transactions
<bean id="pdpReferenceServiceImpl" class="edu.iu.uis.pdp.service.impl.ReferenceServiceImpl"> <property name="referenceDao"><ref local="pdpReferenceDao"/></property></bean>
<bean id="pdpReferenceService” class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref bean="TransactionManager"/></property> <property name="target"><ref bean="pdpReferenceServiceImpl"/></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property></bean>
Example from applicationContext.xml
We control the type of transaction
![Page 92: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/92.jpg)
Transaction Properties
• PROPAGATION_MANDATORY Support a current transaction, throw an exception if none exists.
• PROPAGATION_NEVER Execute non-transactionally, throw an exception if a transaction exists.
• PROPAGATION_NOT_SUPPORTED Execute non-transactionally, suspending the current transaction if one exists.
• PROPAGATION_REQUIRED Support a current transaction, create a new one if none exists.
• PROPAGATION_REQUIRES_NEW Create a new transaction, suspending the current transaction if one exists.
• PROPAGATION_SUPPORTS Support a current transaction, execute non-transactionally if none exists.
* Not all are supported by every transaction manager.
![Page 93: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/93.jpg)
Transaction Properties
• Properties can be applied to methods based on wildcards
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_MANDATORY</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
![Page 94: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/94.jpg)
Transactions
• If necessary, a transaction will Begin before the method is called Commit after the method is finished Rollback if the method throws a Runtime
exception (not a checked exception)
• Rollback behavior can be controlled in the applicationContext file
![Page 95: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/95.jpg)
Transactions
• You can control rollback & commit on specific transactions by listing them in transaction attributes
<property name="transactionAttributes"> <props> <prop key="insert*">PROPAGATION_REQUIRED, -MyCheckedException</prop> <prop key="update*">PROPAGATION_REQUIRED, +NullPointerException</prop> </props>
</property> - means rollback, + means commit
![Page 96: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/96.jpg)
Exercise 10
• Check out FPS/TRAINING/SERVICE1
• Write an implementation of OrderService• Apply these business rules for a save
Use the correct part price based on quantity If the total for a single part is > $100 give a 5%
discount If the total for a single part is > $1000 give a 6%
discount Remember TDD? Use Mock Objects for DAO’s when
testing the service
![Page 97: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/97.jpg)
Architecture
• Our systems should be designed with the following in mind: Readability Flexibility Maintainability Testable
![Page 98: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/98.jpg)
Architecture
• The 3 tier architecture helps us meet those some of these goals
Data Access Business Logic User Interface
![Page 99: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/99.jpg)
Architecture
• Readability - All code of a specific type (data access, business logic, user interface) is in it’s own location
• Flexibility - ?
• Maintainability - See Readability
• Testable - ?
• We can do better
![Page 100: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/100.jpg)
Architecture
OJB or JDBCDAO
OJB or JDBCDAO
Service(business logic)
Service(business logic) Struts
FormsStrutsForms
StrutsActionsStruts
Actions
Business ObjectsBusiness Objects
Ser
vice
Inte
rfac
e
DA
O In
terf
ace
![Page 101: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/101.jpg)
Architecture
• Readability - Same as before• Flexibility - Each tier talks to an interface
for the other tier. The implementation can change all it wants
• Maintainability - See Readability• Testable - We can test each tier
independently by using Mock objects because they communicate via interfaces
![Page 102: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/102.jpg)
DAO - Data Access Object
• DAO’s talk to datasources to create, retrieve, update and delete data
• No business logic allowed
• All JDBC, SQL and/or OJB features should be in these object types and no other object types
• Generally one DAO per table
![Page 103: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/103.jpg)
DAO Interface
• Java interfaces for DAO objects
• Services should only be aware of interface, not actual DAO implementation
• The interface allows the use of Mock objects when testing
![Page 104: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/104.jpg)
Service
• Used for business logic
• Call DAO’s and other Services to access data
• Should not contain SQL, JDBC or web specific information
• Each method will be a single database transaction
![Page 105: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/105.jpg)
Service Interface
• Java interfaces for Service objects
• The interface allows the use of Mock objects when testing
![Page 106: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/106.jpg)
Struts Actions
• Web user interface logic
• No business logic
• Call Services for business logic
• Generally should only call a single method in a service object
![Page 107: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/107.jpg)
Struts Forms
• Only used when a user posts a form to the server• All user edited fields are String properties• Validation should just validate that fields have
the proper format• Validation in the Struts Action should call
business logic• Form objects can contain Business Objects
![Page 108: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/108.jpg)
Business Object
• A Business object is a Javabean (POJO)• There should be a business object for each
entity in the application• Business objects can be used in any tier of
the application• In most cases, Business objects will be
OJB data objects
![Page 109: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/109.jpg)
Isolation
• Each tier should be isolated from other tiers
• A tier shouldn’t have knowledge of how a different tier is implemented
• A tier should only communicate to another tier through a Java interface
• The Spring framework can handle dependencies so each tier is truly isolated
![Page 110: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/110.jpg)
Dependency Injection
• Spring will call set methods on managed objects so other objects don’t need to know details about how a dependant object works
• The dependencies are built into Spring’s context.xml file
![Page 111: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/111.jpg)
Declarative Transactions
• Spring will manage transactions if they are defined in the context.xml
• No code is required to begin, rollback or commit a transaction
• No code is required to open and close database connections
• Spring handles this automatically• No code means you can’t forget it!
![Page 112: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/112.jpg)
Declarative Transactions
• Each method call into a service object is a transaction
• Spring automatically begins the transaction before the method call and ends it after
• If the method throws a runtime exception, Spring rolls back the transaction
![Page 113: Spring/Testing Training](https://reader036.fdocuments.in/reader036/viewer/2022062314/568147ad550346895db4eb1d/html5/thumbnails/113.jpg)
Exceptions
• Runtime Exceptions Use when situation is non-recoverable
• Checked Exceptions Use when situation is recoverable
• Best Practice - fail as soon as possible The closer the failure to the problem, the easier it is to
find the problem
• Best Practice - fail big Hidden failures make it more difficult to fix the problem