├── .gitignore ├── build.gradle ├── src ├── main │ └── java │ │ └── org │ │ └── redlich │ │ └── unit │ │ ├── account │ │ └── Account.java │ │ ├── calculator │ │ └── Calculator.java │ │ ├── hello │ │ └── HelloSpock.java │ │ └── rational │ │ └── Rational.java └── test │ ├── groovy │ └── org │ │ └── redlich │ │ └── unit │ │ ├── account │ │ └── TestAccount.groovy │ │ ├── data │ │ ├── DataDrivenSpec.groovy │ │ └── DatabaseDrivenSpec.groovy │ │ └── hello │ │ └── HelloSpockSpec.groovy │ └── java │ └── org │ └── redlich │ └── unit │ ├── calculator │ └── TestCalculator.java │ ├── hello │ └── TestHelloSpock.java │ └── rational │ └── TestRational.java └── unit-testing-demo.md /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .gradle 3 | .idea 4 | *.iml 5 | *.ipr 6 | *.iws 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | task init() { 2 | println() 3 | println "JUnit and Spock Tests" 4 | println new Date() 5 | println() 6 | } 7 | 8 | apply plugin: 'java' 9 | apply plugin: 'groovy' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | // testCompile group: 'junit', name: 'junit', version: '4.12' 17 | testCompile("junit:junit:4.12") 18 | compile "org.codehaus.groovy:groovy-all:2.4.1" 19 | testCompile "org.spockframework:spock-core:1.0-groovy-2.4" 20 | 21 | // optional dependencies for using Spock 22 | testCompile "org.hamcrest:hamcrest-core:1.3" // only necessary if Hamcrest matchers are used 23 | testRuntime "cglib:cglib-nodep:3.1" // allows mocking of classes (in addition to interfaces) 24 | testRuntime "org.objenesis:objenesis:2.1" // allows mocking of classes without default constructor (together with CGLIB) 25 | 26 | // dependencies used by examples in this project 27 | testRuntime "com.h2database:h2:1.4.182" 28 | 29 | } 30 | 31 | // mainClassName = 'org.redlich.unit.rational.Rational' 32 | 33 | jar { 34 | baseName = 'unit-demo' 35 | version = '1.0.0' 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/redlich/unit/account/Account.java: -------------------------------------------------------------------------------- 1 | package org.redlich.unit.account; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class Account { 6 | private BigDecimal balance = new BigDecimal(0); 7 | 8 | public Account(BigDecimal initial) { 9 | balance = initial; 10 | } 11 | 12 | public BigDecimal getBalance() { 13 | return balance; 14 | } 15 | 16 | public void withdraw(BigDecimal amount) { 17 | if(amount.compareTo(BigDecimal.ZERO) < 0) { 18 | System.out.println("cannot do that..."); 19 | } 20 | balance = balance.subtract(amount); 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/org/redlich/unit/calculator/Calculator.java: -------------------------------------------------------------------------------- 1 | package org.redlich.unit.calculator; 2 | 3 | public class Calculator { 4 | 5 | public int add(int a,int b) { 6 | return a + b; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/org/redlich/unit/hello/HelloSpock.java: -------------------------------------------------------------------------------- 1 | package org.redlich.unit.hello; 2 | 3 | public class HelloSpock { 4 | private String spock = new String(); 5 | private String kirk = new String(); 6 | private String scotty = new String(); 7 | 8 | public HelloSpock() { 9 | setSpock("Spock"); 10 | setKirk("Kirk"); 11 | setScotty("Scotty"); 12 | } 13 | 14 | public String getSpock() { 15 | return spock; 16 | } 17 | 18 | public void setSpock(String spock) { 19 | this.spock = spock; 20 | } 21 | 22 | public String getKirk() { 23 | return kirk; 24 | } 25 | 26 | public void setKirk(String kirk) { 27 | this.kirk = kirk; 28 | } 29 | 30 | public String getScotty() { 31 | return scotty; 32 | } 33 | 34 | public void setScotty(String scotty) { 35 | this.scotty = scotty; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/redlich/unit/rational/Rational.java: -------------------------------------------------------------------------------- 1 | package org.redlich.unit.rational; 2 | 3 | public class Rational { 4 | private int numerator; 5 | private int denominator; 6 | 7 | public Rational() { 8 | this(0,0); 9 | } 10 | 11 | public Rational(int numerator,int denominator) { 12 | this.numerator = numerator; 13 | this.denominator = denominator; 14 | } 15 | 16 | public int getNumerator() { 17 | return numerator; 18 | } 19 | 20 | public int getDenominator() { 21 | return denominator; 22 | } 23 | 24 | public boolean sameDenominator(Rational rational) { 25 | return(getDenominator() == rational.getDenominator()); 26 | } 27 | 28 | public Rational add(Rational rational) { 29 | return new Rational(getNumerator() + rational.getNumerator(),getDenominator()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/groovy/org/redlich/unit/account/TestAccount.groovy: -------------------------------------------------------------------------------- 1 | package org.redlich.unit.account 2 | 3 | import spock.lang.Specification 4 | 5 | class TestAccount extends Specification { 6 | def "withdraw from account" () { 7 | given: 8 | def account = new Account(500.00) 9 | 10 | when: 11 | account.withdraw(200.00) 12 | 13 | then: 14 | account.balance == 300.00 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/groovy/org/redlich/unit/data/DataDrivenSpec.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.redlich.unit.data 18 | 19 | import spock.lang.Specification 20 | import spock.lang.Unroll 21 | 22 | @Unroll 23 | class DataDrivenSpec extends Specification { 24 | def "maximum of two numbers"() { 25 | expect: 26 | Math.max(a, b) == c 27 | 28 | where: 29 | a << [3, 5, 9] 30 | b << [7, 4, 9] 31 | c << [7, 5, 9] 32 | } 33 | 34 | def "minimum of #a and #b is #c"() { 35 | expect: 36 | Math.min(a, b) == c 37 | 38 | where: 39 | a | b || c 40 | 3 | 7 || 3 41 | 5 | 4 || 4 42 | 9 | 9 || 9 43 | } 44 | 45 | def "#person.name is a #sex.toLowerCase() person"() { 46 | expect: 47 | person.getSex() == sex 48 | 49 | where: 50 | person || sex 51 | new Person(name: "Fred") || "Male" 52 | new Person(name: "Wilma") || "Female" 53 | } 54 | 55 | static class Person { 56 | String name 57 | String getSex() { 58 | name == "Fred" ? "Male" : "Female" 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/test/groovy/org/redlich/unit/data/DatabaseDrivenSpec.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.redlich.unit.data 18 | 19 | import groovy.sql.Sql 20 | import spock.lang.Shared 21 | import spock.lang.Specification 22 | 23 | class DatabaseDrivenSpec extends Specification { 24 | @Shared sql = Sql.newInstance("jdbc:h2:mem:","org.h2.Driver") 25 | 26 | // insert data (usually the database would already contain the data) 27 | def setupSpec() { 28 | sql.execute("CREATE TABLE maxdata(id int primary key, a int, b int, c int)") 29 | sql.execute("INSERT INTO maxdata VALUES(1, 3, 7, 7), (2, 5, 4, 5), (3, 9, 9, 9)") 30 | } 31 | 32 | def "maximum of two numbers"() { 33 | expect: 34 | Math.max(a,b) == c 35 | 36 | where: 37 | [a,b,c] << sql.rows("SELECT a, b, c FROM maxdata") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/groovy/org/redlich/unit/hello/HelloSpockSpec.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.redlich.unit.hello 18 | 19 | import spock.lang.Specification 20 | 21 | class HelloSpockSpec extends Specification { 22 | def "length of Spock's and his friends' names"() { 23 | expect: 24 | name.size() == length 25 | 26 | where: 27 | name | length 28 | "Spock" | 5 29 | "Kirk" | 4 30 | "Scotty" | 6 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/redlich/unit/calculator/TestCalculator.java: -------------------------------------------------------------------------------- 1 | package org.redlich.unit.calculator; 2 | 3 | import org.junit.Test; 4 | import static org.junit.Assert.assertEquals; 5 | 6 | public class TestCalculator { 7 | 8 | @Test 9 | public void test() { 10 | assertEquals(3,1 + 2); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/org/redlich/unit/hello/TestHelloSpock.java: -------------------------------------------------------------------------------- 1 | package org.redlich.unit.hello; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import static org.junit.Assert.assertEquals; 6 | 7 | public class TestHelloSpock { 8 | private HelloSpock hellospock; 9 | private String spock; 10 | private String kirk; 11 | private String scotty; 12 | 13 | public TestHelloSpock() { 14 | } 15 | 16 | @Before 17 | public void setup() { 18 | hellospock = new HelloSpock(); 19 | spock = hellospock.getSpock(); 20 | kirk = hellospock.getKirk(); 21 | scotty = hellospock.getScotty(); 22 | } 23 | 24 | @Test 25 | public void testStringLength() { 26 | assertEquals(spock.length(),5); 27 | assertEquals(kirk.length(),4); 28 | assertEquals(scotty.length(),6); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/redlich/unit/rational/TestRational.java: -------------------------------------------------------------------------------- 1 | package org.redlich.unit.rational; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import static org.junit.Assert.assertEquals; 6 | 7 | public class TestRational { 8 | private Rational rational1; 9 | private Rational rational2; 10 | 11 | public TestRational() { 12 | } 13 | 14 | @Before 15 | public void setup() { 16 | rational1 = new Rational(3,2); 17 | rational2 = new Rational(1,2); 18 | } 19 | 20 | @Test 21 | public void testDefault() { 22 | assertEquals(rational1.getNumerator(),3); 23 | assertEquals(rational1.getDenominator(),2); 24 | } 25 | 26 | @Test 27 | public void testPrimary() { 28 | assertEquals(rational2.getNumerator(),1); 29 | assertEquals(rational2.getDenominator(),2); 30 | } 31 | 32 | @Test 33 | public void testSameDenominator() { 34 | assertEquals(rational1.sameDenominator(rational2),true); 35 | } 36 | 37 | @Test 38 | public void testAdd() { 39 | Rational rational3 = rational1.add(rational2); 40 | assertEquals(rational3.getNumerator(),4); 41 | assertEquals(rational3.getDenominator(),2); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /unit-testing-demo.md: -------------------------------------------------------------------------------- 1 | # JUnit and Spock Unit Testing Demo 2 | 3 | ## Introduction 4 | 5 | This JUnit and Spock demo contains tests using both frameworks. 6 | 7 | ## Building and Running the Demo 8 | 9 | This example is built and run using the build tool, [Gradle](http://gradle.org). At the root of the project, simply execute the command: 10 | 11 | `gradle test` 12 | 13 | to run the tests for this demo. Once completed, simply view the `index.html` file in `/build/reports/tests` folder. Just for fun, change one of the tests such that it fails and re-execute the tests to see what happens. 14 | 15 | Enjoy! 16 | 17 | Mike Redlich 18 | 19 | [redlich.net](http://www.redlich.net/) 20 | 21 | [mike@redlich.net](mailto:mike@redlich.net) 22 | 23 | 24 | 25 | 26 | --------------------------------------------------------------------------------