Understanding @Unroll and parametization

1,081 views
Skip to first unread message

groovybayo

unread,
Dec 7, 2011, 1:00:23 PM12/7/11
to Spock Framework - User
I have been trying to wrap my head around spock parameterization and
still banging my head against the wall here.

So I have a sample that users spring and hibernate, and I want to
write a feature that will read all the rows of a particular table
(which is already mapping into a domain entity), and then perform a
series of checks on the retrieved entity.

How will I go about writing this using parameterization?

Using this...

@ContextConfiguration(locations="classpath:my-context.xml")
@Transactional
class HelloWorldSpec extends Specification {

@Autowired SessionFactory sessionFactory

def "test spock parameterization"(){

expect:
entity != null

where:
entity <<
sessionFactory.getCurrentSession().createCriteria(Foo.class).list()
}
}

I get an error on the where block saying

Only @Shared and static fields may be accessed from here

Since they session factory needs to be injected, I can't make it
static.

So is there a workaround for something like this?

Thanks

Dan Durkin

unread,
Dec 7, 2011, 1:15:40 PM12/7/11
to spockfr...@googlegroups.com
have you tried using the @Shared annotation or can you not use it for
some reason?

> --
> You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
> To post to this group, send email to spockfr...@googlegroups.com.
> To unsubscribe from this group, send email to spockframewor...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/spockframework?hl=en.
>

groovybayo

unread,
Dec 7, 2011, 1:28:30 PM12/7/11
to Spock Framework - User
I tried that already Dan

If I use @Shared on sessionFactory, I get...

Internal Error occured.
org.spockframework.spring.SpringExtensionException: @Shared field
'sessionFactory' cannot be injected; use an instance field instead
at
org.spockframework.spring.SpringExtension.checkNoSharedFieldsInjected(SpringExtension.java:
61)
at
org.spockframework.spring.SpringExtension.visitSpec(SpringExtension.java:
35)
at
org.spockframework.runtime.ExtensionRunner.runGlobalExtensions(ExtensionRunner.java:
44)
at
org.spockframework.runtime.ExtensionRunner.run(ExtensionRunner.java:
38)
at
org.spockframework.runtime.Sputnik.runExtensionsIfNecessary(Sputnik.java:
80)
at org.spockframework.runtime.Sputnik.getDescription(Sputnik.java:49)

Frederic Pape

unread,
Dec 8, 2011, 2:05:07 AM12/8/11
to Spock Framework - User
Hi,

I don't think it's currently possible to do this with parameterization
a this workaround may:

@ContextConfiguration(locations="classpath:my-context.xml")
@Transactional
class HelloWorldSpec extends Specification {
@Autowired SessionFactory sessionFactory
def "test spock parameterization"(){

when:
def allEntities =
sessionFactory.getCurrentSession().createCriteria(Foo.class).list()
then:
allEntities.each { entity ->
assert entity != null
}

}
}


With kind regards,
Frederic

groovybayo

unread,
Dec 8, 2011, 10:49:48 AM12/8/11
to Spock Framework - User
Thanks Frederic. That works. I have always thought the then block
could only contain conditions and the like.

According to the docs @ http://code.google.com/p/spock/wiki/SpockBasics,
under When and Then Blocks section

The when and then blocks always occur together. They describe a
stimulus and the expected response. Whereas when blocks may contain
arbitrary code, then blocks are restricted to conditions, exception
conditions, interactions, and variable definitions. A feature method
may contain multiple pairs of when-then blocks.

So a follow up question is what is the benefit of using when-then
block in this case, when this could have also all been done in the
setup block as well, like so...

def "test doing it all in setup"() {
setup:
def entities =
sessionFactory.currentSession.createCriteria(Foo.class).list()
entities.each {
assert it != null
}
}

I am just curious

Frederic Pape

unread,
Dec 9, 2011, 3:05:25 AM12/9/11
to Spock Framework - User

It just a way of structuring your test: before I was using spock my
junit tests looked like this:

@ContextConfiguration(locations="classpath:my-context.xml")
@Transactional
public class HelloWorldTest {
@Autowired SessionFactory sessionFactory

@Test
public void testFoo(){
// given
def criteria =
sessionFactory.getCurrentSession().createCriteria(Foo.class)
// when
def allEntities = criteria.list()
// then


allEntities.each { entity ->
assert entity != null
}
}
}

So I was already using given-when-then but then in the comment blocks.
It helps me to keep my tests maintainable.

With kind regards,
Frederic

On Dec 8, 4:49 pm, groovybayo <groovyb...@gmail.com> wrote:
> Thanks Frederic. That works. I have always thought the then block
> could only contain conditions and the like.
>

> According to the docs @http://code.google.com/p/spock/wiki/SpockBasics,

Peter Niederwieser

unread,
Dec 9, 2011, 3:19:53 PM12/9/11
to spockfr...@googlegroups.com
On 08.12.2011, at 16:49, groovybayo wrote:

> Thanks Frederic. That works. I have always thought the then block
> could only contain conditions and the like.

Yes, this is correct. One exception is that an invocation of a "void" method will not be interpreted as a condition. For example, this allows to add a println statement for debugging purposes.

> So a follow up question is what is the benefit of using when-then
> block in this case, when this could have also all been done in the
> setup block as well, like so...

Some benefits are:
* It makes the test more readable
* It makes clear what you are (not) testing
* You don't need an explicit assert
* You can use thrown() and old()
* Mock interactions in a then-block are scoped to the corresponding when-block

Cheers,
Peter

Reply all
Reply to author
Forward
0 new messages