Download presentation
Presentation is loading. Please wait.
Published byPiers Lucas Modified over 8 years ago
2
21 Oct 2008Presentation to PJUG2 Unit Testing Java Code with Howard Abrams howard@howardabrams.co m
3
21 Oct 2008Presentation to PJUG3 Why use Groovy for Unit Testing? ● Scripting language advantages ● Quick development (RAD)... inclined to write tests ● Higher-level programming... easier to maintain ● More features than Java ● Groovy integrates seamlessly with Java ● Extends JUnit, but still works like JUnit ● Good integration with Mocking Libraries ● Integrates with Ant and Maven
4
21 Oct 2008Presentation to PJUG4 Groovy Goodies ● Syntactic Sugar Coating ● Lists and Maps are first-class types ● Closures ● Builders and other helpers like XmlSlurper ● Object runtime alteration ● Mocks ● Dynamic Code — Evaluating expressions ● Write code to generate script code
5
21 Oct 2008Presentation to PJUG5 Java to Groovy Conversion public class Foobar { int prop = 5; List l = new ArrayList(); Foobar() { l.add ( 6 ); l.add (10); l.add (12.5); } Object doSomething() { System.out.println ("Working with " + prop+" property."); if ( prop < 5 ) return prop * 1.5; else return prop * 100; } public int getProp() { return prop; } public void setProp (int prop) { this.prop = prop; } public class Foobar { int prop = 5; List l = new ArrayList() Foobar() { l.add 6 l.add 10 l.add 12.5 } Object doSomething() { System.out.println ("Working with " + prop+" property.") if ( prop < 5 ) return prop * 1.5 else return prop * 100 } public int getProp() { return prop } public void setProp (int prop) { this.prop = prop } public class Foobar { int prop = 5; List l = new ArrayList() Foobar() { l.add 6 l.add 10 l.add 12.5 } Object doSomething() { println "Working with "+prop+" property." if ( prop < 5 ) return prop * 1.5 else return prop * 100 } public int getProp() { return prop } public void setProp (int prop) { this.prop = prop } public class Foobar { int prop = 5; List l = new ArrayList() Foobar() { l.add 6 l.add 10 l.add 12.5 } Object doSomething() { println "Working with "+prop+" property." if ( prop < 5 ) return prop * 1.5 else return prop * 100 } public class Foobar { int prop = 5; List l = [ 6, 10, 12.5 ] Foobar() { } Object doSomething() { println "Working with "+prop+" property." if ( prop < 5 ) return prop * 1.5 else return prop * 100 } public class Foobar { int prop = 5; List l = [ 6, 10, 12.5 ] Foobar() { } Object doSomething() { println "Working with ${prop} property." if ( prop < 5 ) return prop * 1.5 else return prop * 100 } public class Foobar { def prop = 5; def l = [ 6, 10, 12.5 ] def doSomething() { println "Working with ${prop} property." if ( prop < 5 ) return prop * 1.5 else return prop * 100 }
6
21 Oct 2008Presentation to PJUG6 Integrates Seamlessly with Java ● Java code is Groovy code ● Don't know how to write Groovy, write it in Java first. ● Groovy code compiles to Java class files ● Depends on groovy.jar ● The groovyc compiler can compile Java files ● Groovy classes extend Java classes
7
21 Oct 2008Presentation to PJUG7 Extends JUnit ● GroovyTestCase extends junit.framework.TestCase ● IDEs treat a Groovy test like JUnit ● Additional asserts: ● assertArrayEquals ( array1, array2 ) ● assertLength ( value, array ) ● assertContains ( object, array ) ● shouldFail {... }
8
21 Oct 2008Presentation to PJUG8 Square Class public class Square { int x; int y; int height; int width; /** * Returns the area associated with this square. * @return The area == width * height * @throws IllegalStateException If the properties are not set. */ public int area() throws IllegalStateException { if ( width < 0 || height < 0 ) throw new IllegalStateException("Not properly set up."); return width * height; } // What follows is the getters/setters, etc...
9
21 Oct 2008Presentation to PJUG9 Square Tests public class SquareTests extends GroovyTestCase { @Test void testArea() { def sq = new Square ( width:4, height:3 ) assert 12 == sq.area() } @Test void testBadArea() { def sq = new Square ( width: -1, height: 4 ) shouldFail ( IllegalStateException ) { sq.area() } ● Instantiate objects and set properties at one time ● Normally we use assert instead of assertTrue ● Catch exceptions with shouldFail closure
10
21 Oct 2008Presentation to PJUG10 assertArrayEquals() /** * Like the string's {@link String#split(String)} method, but returns the * delimiter... oh, and it doesn't take a regular expression. * * @param original The string to parse * @param delimiter The character(s) to use as splitting tokens * @return An array of the strings split. */ public static String[] split ( String original, String delimiter ); @Test void testSplit() { def original = "foo:and:bar" def delimiter = ':' def expected = [ 'foo', ':', 'and', ':', 'bar' ] assertArrayEquals ( expected, Utilities.split(original, delimiter) ) } Java Code to test... (Interface) Groovy Test Case...
11
21 Oct 2008Presentation to PJUG11 Groovy Test Suites import junit.framework.* static Test suite() { def suite = new TestSuite() def gsuite = new GroovyTestSuite() suite.addTestSuite( gsuite.compile( "SquareTests.groovy" )) suite.addTestSuite( gsuite.compile( "UtilitiesTests.groovy")) //... return suite } junit.textui.TestRunner.run(suite()) ● Create a standard JUnit test suite ● Use the GroovyTestSuite class to compile Groovy code
12
21 Oct 2008Presentation to PJUG12 AllTestSuite ● The AllTestSuite helper builds JUnit test suites. ● Takes a collection of Groovy files. ● First argument is a directory ● Second is a filename pattern ● Returns a JUnit TestSuite def suite = AllTestSuite.suite(".", "*Tests.groovy") junit.textui.TestRunner.run(suite)
13
21 Oct 2008Presentation to PJUG13 Collaborators ● Code depends on a component (poss. w/Interface) ● Component can be replaced (with a method call) /** * The Collaborator Interface */ public interface Bar { /** * Returns the random value. * @return Returns something. */ public String something(); } public class Foo { Bar bar; // Setter for the "bar" property. public void setBar (Bar bar) { this.bar = bar; } /** * Returns a random value times 100. * @return A random value. */ public String getValue() { if ( bar == null ) throw new IllegalStateException("'bar' property not set."); return bar.something() + "..."; }
14
21 Oct 2008Presentation to PJUG14 Testing Collaborators ● Goal: Test a single class (CUT) in isolation ● Minimize issues introduced by dependent code ● The domain of creating Mock classes class FooTests extends GroovyTestCase { void testGetValue() { def barMock = new BarMock ( value:'Hello' ) Foo foo = new Foo ( bar:barMock ) assert 'Hello...' == foo.value } class BarMock implements Bar { String value String something() { return value }
15
21 Oct 2008Presentation to PJUG15 Using Mock Libraries ● Mock Libraries are often helpful ● Popular library: EasyMockEasyMock ● I like jMock... with a bit of an extension:jMock /** * Taken from the Codehaus Groovy site. Sure hope they don't mind. * @see JMock */ public class JUnit4GroovyMockery extends JUnit4Mockery { class ClosureExpectations extends org.jmock.Expectations { void closureInit(Closure cl, Object delegate) { cl.setDelegate(delegate); cl.call(); } public void checking(Closure c) { ClosureExpectations expectations = new ClosureExpectations(); expectations.closureInit(c, expectations); super.checking(expectations); }
16
21 Oct 2008Presentation to PJUG16 Testing with jMock final Mockery context = new JUnit4GroovyMockery() @Test void testGetValue() { mockBar = context.mock ( Bar.class ) context.checking { // How shall Mock act? one(mockBar).something(); will(returnValue("Hello")) one(mockBar).something(); will(returnValue("Good-bye")) } foo = new Foo( bar:mockBar ) assert foo.value == "Hello..." assert foo.value == "Good-bye..." }
17
21 Oct 2008Presentation to PJUG17 Ant Integration <taskdef name="groovyc" classname="org.codehaus.groovy.ant.Groovyc" classpath="/usr/java/groovy/embedded/groovy-all- 1.5.6.jar"/> <groovyc srcdir ="${testSourceDirectory}" destdir="${testClassesDirectory}"> ● Add groovy-all-VERSION.jar to my.classpath: ● Joint compilation of both Java and Groovy:
18
21 Oct 2008Presentation to PJUG18 Using the JUnit Task ● JUnit task typically specifies *.java... not classes ● Must be careful to not specify internal classes:
19
21 Oct 2008Presentation to PJUG19 Groovy in Ant ● Add the Groovy Task: ● Add scripting to your build process: <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpath="/usr/java/groovy/embedded/groovy-all-1.5.6.jar"/> xmlfiles = new File(".").listFiles().findAll{ it =~ "\.xml$" } xmlfiles.sort().each { println it.toString() }
20
21 Oct 2008Presentation to PJUG20 Gant – Groovy Build Process ● Specify a build process using Groovy syntax: ● Includes closures and scripting capabilities ● Excludes closing tags. includeTargets << gant.targets.Clean cleanPattern << [ '**/*~', '**/*.bak' ] cleanDirectory << 'build' ant.taskdef ( name:'groovyc', classname:'org.codehaus.groovy.ant.Groovyc') target ( stuff : 'A target to do some stuff.' ) { println ( 'Stuff' ) depends ( clean ) echo ( message : 'A default message from Ant.' ) otherStuff ( ) } target ( otherStuff : 'A target to do some other stuff' ) { println ( 'OtherStuff' ) echo ( message : 'Another message from Ant.' ) clean ( ) } setDefaultTarget ( stuff )
21
21 Oct 2008Presentation to PJUG21 Gant Features ● Targets can be build programmatically: ● Compiling Example: aTargetName = 'something' target ( ( aTargetName ) : 'A target called' + aTargetName + '.' ) { println ( 'Executing ' + aTargetName ) } ant.taskdef ( name : 'groovyc', classname : 'org.codehaus.groovy.ant.Groovyc' ) target ( compile : 'Compile source to build directory.' ) { javac ( srcdir : sourceDirectory, destdir : buildDirectory, debug : 'on' ) groovyc ( srcdir : sourceDirectory, destdir : buildDirectory ) }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.