Sometimes we are working on a new feature in our code and we want to write a specification for it without yet really implementing the feature.
To indicate we know the specification will fail while we are implementing the feature we can add the @PendingFeature
annotation to our specification method.
With this annotation Spock will still execute the test, but will set the status to ignored if the test fails.
But if the test passes the status is set to failed.
So when we have finished the feature we need to remove the annotation and Spock will kindly remind us to do so this way.
In the following example specification we use the @PendingFeature
annotation:
Continue reading →
When we write a feature method in our Spock specification to test our class we might run into long running methods that are invoked.
We can specify a maximum time we want to wait for a method.
If the time spent by the method is more than the maximum time our feature method must fail.
Spock has the @Timeout
annotation to define this.
We can apply the annotation to our specification or to feature methods in the specification.
We specify the timeout value as argument for the @Timeout
annotation.
Seconds are the default time unit that is used.
If we want to specify a different time unit we can use the annotation argument unit
and use constants from java.util.concurrent.TimeUnit
to set a value.
In the following example specification we set a general timeout of 1 second for the whole specification.
For two methods we override this default timeout with their own value and unit:
Continue reading →
To ignore feature methods in our Spock specification we can use the annotation @Ignore
.
Any feature method or specification with this annotation is not invoked when we run a specification.
With the annotation @IgnoreRest
we indicate that feature methods that do not have this annotation must be ignored.
So any method with the annotation is invoked, but the ones without aren’t.
This annotation can only be applied to methods and not to a specification class.
In the next example we have a specification with two feature methods that will be executed and one that is ignored:
Continue reading →
Although I couldn't make it to Gr8Conf EU this year, I am glad a lot of the presentations are available as slide decks and videos.
The slide deck for the talk Interesting nooks and crannies of Spock you (may) have never seen before by Marcin Zajączkowski is very interesting.
This is really a must read if you use Spock (and why shouldn't you) in your projects.
One of the interesting things is the ability to change the response for methods in a class that is stubbed using Spock's Stub
method, but have no explicit stubbed method definition.
So normally when we create a stub we would add code that implements the methods from the stubbed class.
In our specification the methods we have written are invoked instead of the original methods from the stubbed class.
By default if we don't override a method definition, but it is used in the specification, Spock will try to create a response using a default response strategy.
The default response strategy for a stub is implemented by the class EmptyOrDummyResponse
.
For example if a method has a return type Message
then Spock will create a new instance of Message
and return it to be used in the specification.
Spock also has a ZeroOrNullResponse
response strategy.
With this strategy null
is returned for our method that returns the Message
type.
Continue reading →
In a previous post we learned that we can check a specific exception is not thrown in our specification with the notThrown
method.
If we are not interested in a specific exception, but just want to check no exception at all is thrown, we must use the noExceptionThrown
method.
This method return true
if the called code doesn't throw an exception.
In the following example we invoke a method (cook
) that can throw an exception.
We want to test the case when no exception is thrown:
Continue reading →
In a Spock specification we write our assertion in the then:
or expect:
blocks. If we need to write multiple assertions for an object we can group those with the with
method. We specify the object we want write assertions for as argument followed by a closure with the real assertions. We don't need to use the assert
keyword inside the closure, just as we don't have to use the assert
keyword in an expect:
or then:
block.
In the following example specification we have a very simple implementation for finding an User
object. We want to check that the properties username
and name
have the correct value.
Continue reading →
In a previous post we saw how can use the Spock configuration file to include or exclude specifications based on annotations. Instead of using annotations we can also use classes to include or exclude specifications. For example we could have a base specification class DatabaseSpecification
. Other specifications dealing with databases extend this class. To include all these specifications we use the DatabaseSpecification
as value for the include
property for the test runner configuration.
Because Java (and Groovy) doesn't support real multiple inheritance this might be a problem if we already have specifications that extends a base class, but the base class cannot be used as filter for the include
and exclude
runner configuration. Luckily we can also use an interface as the value for the inclusion or exclusion. So we could simple create a marker interface and implement this interface for these specifications we want to include or exclude from the test execution.
Continue reading →
One of the handy features of Groovy is to change the behavior of classes using MOP (Meta-Object Protocol). We change the metaClass
property of a class to alter an implementation. You can for example override a static method of a class. See the example below:
class UserSpec extends Specification {
def “test user”() {
given:
// we can mock static methods...
User.metaClass.static.findByName = { name ->
new User(name: ‘Albert’) }
when:
User user = User.findByName(‘Albert’)
then:
user.name == ‘Albert’
when:
// .. but also non-static methods
user.metaClass.getName = { return ‘Dries’ }
then:
user.name == ‘Dries’
}
}
Continue reading →