-
Notifications
You must be signed in to change notification settings - Fork 471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prefer block name 'given' over 'setup' #786
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,10 +15,11 @@ To learn more about unit testing, go to http://en.wikipedia.org/wiki/Unit_testin | |
|
||
== Terminology | ||
|
||
Let's start with a few definitions: Spock lets you write _specifications_ that describe expected _features_ (properties, | ||
aspects) exhibited by a system of interest. The system of interest could be anything between a single class and a whole | ||
application, and is also called _system under specification (SUS)_. The description of a feature starts from a specific | ||
snapshot of the SUS and its collaborators; this snapshot is called the feature's _fixture_. | ||
Let's start with a few definitions: Spock lets you write https://en.wikipedia.org/wiki/Specification_by_example[_specifications_] | ||
that describe expected _features_ (properties, aspects) exhibited by a system of interest. The system of interest could be | ||
anything between a single class and a whole application, and is also called the _system under specification or SUS_. | ||
The description of a feature starts from a specific snapshot of the SUS and its collaborators; this snapshot is called | ||
the feature's _fixture_. | ||
|
||
The following sections walk you through all building blocks of which a Spock specification may be composed. A typical | ||
specification uses only a subset of them. | ||
|
@@ -88,10 +89,10 @@ respect to sharing are more well-defined. | |
|
||
[source,groovy] | ||
---- | ||
def setup() {} // run before every feature method | ||
def cleanup() {} // run after every feature method | ||
def setupSpec() {} // run before the first feature method | ||
def cleanupSpec() {} // run after the last feature method | ||
def setupSpec() {} // runs once - before the first feature method | ||
def setup() {} // runs before every feature method | ||
def cleanup() {} // runs after every feature method | ||
def cleanupSpec() {} // runs once - after the last feature method | ||
---- | ||
|
||
Fixture methods are responsible for setting up and cleaning up the environment in which feature methods are run. | ||
|
@@ -135,8 +136,8 @@ interacting feature methods), and may occur more than once. | |
|
||
Spock has built-in support for implementing each of the conceptual phases of a feature method. To this end, feature | ||
methods are structured into so-called _blocks_. Blocks start with a label, and extend to the beginning of the next block, | ||
or the end of the method. There are six kinds of blocks: `setup`, `when`, `then`, `expect`, `cleanup`, and `where` blocks. | ||
Any statements between the beginning of the method and the first explicit block belong to an implicit `setup` block. | ||
or the end of the method. There are six kinds of blocks: `given`, `when`, `then`, `expect`, `cleanup`, and `where` blocks. | ||
Any statements between the beginning of the method and the first explicit block belong to an implicit `given` given block. | ||
|
||
A feature method must have at least one explicit (i.e. labelled) block - in fact, the presence of an explicit block is | ||
what makes a method a feature method. Blocks divide a method into distinct sections, and cannot be nested. | ||
|
@@ -149,19 +150,19 @@ The picture on the right shows how blocks map to the conceptual phases of a feat | |
special role, which will be revealed shortly. But first, let's have a closer look at the other blocks. | ||
-- | ||
|
||
==== Setup Blocks | ||
==== Given Blocks | ||
|
||
[source,groovy] | ||
---- | ||
setup: | ||
given: | ||
def stack = new Stack() | ||
def elem = "push me" | ||
---- | ||
|
||
The `setup` block is where you do any setup work for the feature that you are describing. It may not be preceded by | ||
other blocks, and may not be repeated. A `setup` block doesn't have any special semantics. The `setup:` label is | ||
optional and may be omitted, resulting in an _implicit_ `setup` block. The `given:` label is an alias for `setup:`, | ||
and sometimes leads to a more readable feature method description (see <<specs-as-doc,Specifications as Documentation>>). | ||
The `given` block is where you do any configuration for the feature that you are describing. It may not be preceded by | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change made. |
||
other blocks, and may not be repeated. A `given` block doesn't have any special semantics. The `given:` label is | ||
optional and may be omitted, resulting in an _implicit_ `given` block. Originally, the alias `setup:` was the preferred block name, | ||
but using `given:` often leads to a more readable feature method description (see <<specifications_as_documentation,Specifications as Documentation>>). | ||
|
||
==== When and Then Blocks | ||
|
||
|
@@ -293,7 +294,7 @@ implementing this method? After all, where are the conditions? Fortunately, we c | |
[source,groovy] | ||
---- | ||
def "HashMap accepts null key"() { | ||
setup: | ||
given: | ||
def map = new HashMap() | ||
|
||
when: | ||
|
@@ -311,8 +312,9 @@ the method will also fail if any other exception is thrown. | |
===== Interactions | ||
|
||
Whereas conditions describe an object's state, interactions describe how objects communicate with each other. | ||
Interactions are devoted a whole <<interaction_based_testing.adoc#,chapter>>, and so we only give a quick example here. | ||
Suppose we want to describe the flow of events from a publisher to its subscribers. Here is the code: | ||
Interactions and Interaction based testing are described in a separate <<interaction_based_testing.adoc#,chapter>>, | ||
so we only give a quick example here. Suppose we want to describe the flow of events from a publisher to its subscribers. | ||
Here is the code: | ||
|
||
[source,groovy] | ||
---- | ||
|
@@ -363,7 +365,7 @@ to create more expressive and succinct conditions. | |
|
||
[source,groovy] | ||
---- | ||
setup: | ||
given: | ||
def file = new File("/some/path") | ||
file.createNewFile() | ||
|
||
|
@@ -386,7 +388,7 @@ is automatically reclaimed by the garbage collector. More coarse-grained specifi | |
block to clean up the file system, close a database connection, or shut down a network service. | ||
|
||
TIP: If a specification is designed in such a way that all its feature methods require the same resources, use a | ||
`cleanup()` method; otherwise, prefer `cleanup` blocks. The same trade-off applies to `setup()` methods and `setup` blocks. | ||
`cleanup()` method; otherwise, prefer `cleanup` blocks. The same trade-off applies to `setup()` methods and `given` blocks. | ||
|
||
==== Where Blocks | ||
|
||
|
@@ -409,9 +411,9 @@ def "computing the maximum of two numbers"() { | |
This `where` block effectively creates two "versions" of the feature method: One where `a` is 5, `b` is 1, and `c` is 5, | ||
and another one where `a` is 3, `b` is 9, and `c` is 9. | ||
|
||
Although it is declared last the `where` block is evaluated before feature method runs. | ||
Although it is declared last, the `where` block is evaluated before the feature method containing it runs. | ||
|
||
The `where` block will be further explained in the <<data_driven_testing.adoc#,Data Driven Testing>> chapter. | ||
The `where` block is further explained in the <<data_driven_testing.adoc#,Data Driven Testing>> chapter. | ||
|
||
== Helper Methods | ||
|
||
|
@@ -498,7 +500,6 @@ A final advice: Although code reuse is generally a good thing, don't take it too | |
and helper methods can increase the coupling between feature methods. If you reuse too much or the wrong code, you will | ||
end up with specifications that are fragile and hard to evolve. | ||
|
||
[[specs-as-doc]] | ||
|
||
== Using `with` for expectations | ||
|
||
|
@@ -540,6 +541,8 @@ with(service) { | |
1 * stop() | ||
} | ||
---- | ||
|
||
[[specifications_as_documentation]] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will conflict with your other #787 please align them There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added these lines to this file in #787 per request. |
||
== Specifications as Documentation | ||
|
||
Well-written specifications are a valuable source of information. Especially for higher-level specifications targeting | ||
|
@@ -549,15 +552,15 @@ attach textual descriptions to blocks: | |
|
||
[source,groovy] | ||
---- | ||
setup: "open a database connection" | ||
given: "open a database connection" | ||
// code goes here | ||
---- | ||
|
||
Individual parts of a block can be described with `and:`: | ||
Use the `and:` label to describe logically different parts of a block: | ||
|
||
[source,groovy] | ||
---- | ||
setup: "open a database connection" | ||
given: "open a database connection" | ||
// code goes here | ||
|
||
and: "seed the customer table" | ||
|
@@ -585,8 +588,6 @@ then: "the account's balance is $10" | |
// ... | ||
---- | ||
|
||
As noted before, `given:` is just an alias for `setup:`. | ||
|
||
Block descriptions are not only present in source code, but are also available to the Spock runtime. Planned usages of | ||
block descriptions are enhanced diagnostic messages, and textual reports that are equally understood by all stakeholders. | ||
|
||
|
@@ -599,19 +600,21 @@ activated by annotations called _directives_. Currently, Spock ships with the fo | |
[horizontal] | ||
`@Timeout`:: Sets a timeout for execution of a feature or fixture method. | ||
|
||
`@Ignore`:: Ignores a feature method. | ||
`@Ignore`:: Ignores any feature method carrying this annotation. | ||
|
||
`@IgnoreRest`:: Ignores all feature methods not carrying this annotation. Useful for quickly running just a single method. | ||
`@IgnoreRest`:: Any feature method carrying this annotation will be executed, all others will be ignored. Useful | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please set your IDE to softwraps instead of introducing needless newlines. Also fix the other additional line breaks. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change made to align with current line breaks. |
||
for quickly running just a single method. | ||
|
||
`@FailsWith`:: Expects a feature method to complete abruptly. `@FailsWith` has two use cases: First, to document known bugs that cannot | ||
be resolved immediately. Second, to replace exception conditions in certain corner cases where the latter cannot be | ||
used (like specifying the behavior of exception conditions). In all other cases, exception conditions are preferable. | ||
`@FailsWith`:: Expects a feature method to complete abruptly. `@FailsWith` has two use cases: First, to document | ||
known bugs that cannot be resolved immediately. Second, to replace exception conditions in certain corner cases | ||
where the latter cannot be used (like specifying the behavior of exception conditions). In all other cases, | ||
exception conditions are preferable. | ||
|
||
To learn how to implement your own directives and extensions, go to the <<extensions.adoc#,Extensions>> chapter. | ||
Go to the <<extensions.adoc#,Extensions>> chapter to learn how to implement your own directives and extensions. | ||
|
||
== Comparison to JUnit | ||
|
||
Although Spock uses a different terminology, many of its concepts and features are inspired from JUnit. Here is a rough | ||
Although Spock uses a different terminology, many of its concepts and features are inspired by JUnit. Here is a rough | ||
comparison: | ||
|
||
|=== | ||
|
@@ -629,3 +632,4 @@ comparison: | |
|Exception condition |`@Test(expected=...)` | ||
|Interaction | Mock expectation (e.g. in Mockito) | ||
|=== | ||
` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one
given
to manyThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change made.