On Github tbialecki / spock-workshop-lectures
... a developer testing and specification framework
... for Java and Groovy
... compatible with most IDEs, build tools, and continuous integration servers
... is inspired from JUnit, jMock, RSpec, Groovy, Scala, Vulcans
public class HelloWorldTest {
@Test
public void plusPlusIShouldIterate() {
//given
int i = 0;
//when
i = ++i;
//then
assertEquals(i, 1);
}
}
class HelloWorldTest extends Specification {
def "++i should iterate"() {
given:
def i = 0
when:
i = ++i
then:
i == 1
}
}
class HelloWorldTest extends Specification {
def "++i should iterate"() {
given: "i variable"
def i = 0
when: "using ++ operator"
i = ++i
then: "i should be equal 1"
i == 1
}
}
class HelloWorldTest extends Specification {
def "++i should iterate"() {
given: "i variable"
def i = 0
and: "some programming skills"
//the programming skills
when: "using ++ operator"
i = ++i
then: "i should be equal 1"
i == 1
}
}
class HelloWorldTest extends Specification {
def "++i should iterate"() {
given:
def i = 0
expect:
++i == 1
}
}
class LifecycleTest extends Specification {
@Shared
def objectUnderTest = new Simple();
def setup() { ... }
def cleanup() { ... }
def setupSpec() { ... }
def cleanupSpec() { ... }
}
class HelloWorldTest extends Specification {
def "failing tests should give reasonable output message"() {
when:
def list = [[1, 2, 3], [2, 3, 4]];
then:
list.get(0).sum() == 7
}
}
Condition not satisfied: list.get(0).sum() == 7 | | | | | | 6 false | [1, 2, 3] [[1, 2, 3], [2, 3, 4]]
...
class DataDrivenTest extends Specification {
def "Math.max should determine max value"(int a, int b, int max) {
expect:
Math.max(a, b) == max
where:
a | b || max
1 | 2 || 2
1 | 1 || 1
3 | 2 || 3
}
}
class DataDrivenTest extends Specification {
def "Math.max should determine max value"() {
expect:
Math.max(a, b) == max
where:
a | b || max
1 | 2 || 2
1 | 1 || 1
3 | 2 || 3
}
}
class DataDrivenTest extends Specification {
def "Math.max should determine max value"(int a, int b, int max) {
expect:
Math.max(a, b) == max
where:
a << [1, 1, 3]
b << [2, 1, 2]
max << [2, 1, 3]
}
}
...
Own mocking implementation
... tightly integrated with Spock features
... but not obligatory
class Publisher {
List<Subscriber> subscribers
void send(String message)
}
interface Subscriber {
void receive(String message)
}
def "should notify subscriber"() {
given:
def publisher = new Publisher();
def subscriber = Mock(Subscriber);
publisher.subscribers << subscriber;
when:
publisher.send("hello")
then:
1 * subscriber.receive("hello")
}
1 * subscriber.receive("hello") // exactly one call
0 * subscriber.receive("hello") // zero calls
(1..3) * subscriber.receive("hello") // between one and three calls
(1.._) * subscriber.receive("hello") // at least one call
(_..3) * subscriber.receive("hello") // at most three calls
1 * subscriber.receive("hello") // a call to 'subscriber'
1 * _.receive("hello") // a call to any mock object
1 * subscriber.receive("hello") // a method named 'receive'
1 * subscriber./r.*e/("hello") // a method whose name matches
// the given regular expression
1 * subscriber.receive("hello") // an argument that is equal
// to the String "hello"
1 * subscriber.receive(!"hello") // an argument that is unequal
// to the String "hello"
1 * subscriber.receive() // the empty argument list
1 * subscriber.receive(_) // any single argument
1 * subscriber.receive(*_) // any argument list
1 * subscriber.receive(!null) // any non-null argument
1 * subscriber.receive(_ as String) // any non-null argument
// that is-a String
1 * subscriber.receive({ it.size() > 3 })
// an argument that satisfies
// the given predicate
1 * process.invoke("ls", "-a", _, !null, { ["abcd"].contains(it) })
interface Subscriber {
String receive(String message)
}
subscriber.receive("message1") >> "ok"
subscriber.receive("message2") >> "fail"
subscriber.receive(_) >>> ["ok", "error", "error", "ok"]
subscriber.receive(_) >> { args -> args[0].size()>3 ? "ok": "nok" }
subscriber.receive(_) >>> ["ok", "fail", "ok"]
>> { throw new InternalError() } >> "ok"
@Ignore
def "I won't run"() { ... }
@IgnoreRest
def "Only it will run"() { ... }
@IgnoreIf({ os.windows })
def "I'll run everywhere but on Windows"() { ... }
@Requires({ os.windows })
def "I'll only run on Windows"() { ... }
@Stepwise
class RunInOrderSpec extends Specification { ... }
@Timeout(10)
class TimedSpec extends Specification { ... }
@ContextConfiguration(classes = SampleComponentTestConfig)
class SampleComponentTest extends Specification {
@Autowired
SampleComponent sampleComponent;
def "should do it"() {
when:
def output = sampleComponent.doIt();
then:
output == "I`m doing";
}
@Configuration
public static class SampleComponentTestConfig {
@Bean
public SampleComponent sampleComponent() {
return new SampleComponent();
}
}
}