- general advantages to Groovy
- apply also to JUnit
- Closures for assertions - e.g.
assert collection.every { it > x }
- no need to declare exceptions on test methods
- show
expect
- implicit assertion
- show power assert diagnostic
- show
when
/then
- prepare, act, assert:
when
is the act,then
is the assert
- prepare, act, assert:
- show
given
- discuss
when
/then
vsgiven
/expect
- explain
and
- discuss
Discuss…
setup
method- labelling blocks
- not just comments - retained in bytecode
- one of the most painful things in JUnit
- behaviour of data setup method is complex
- how many dimensions in that array?
- results are reported separately but no description
- cannot use different parameters for different test methods
- okay, you can in recent versions with
@DataProvider
- okay, you can in recent versions with
- data setup is a little easier
- no separate reporting
- this really sucks
- show it breaking; change
insert(coin)
toinsert(coins[0])
- might as well just use a loop
- again parameters are per class not per test
- data pipe
- can be any
Iterable
, e.g. a method call - add calculated param
expectedValue
- show
@Unroll
- at method level with auto-complete in pattern
- report implications
- move pattern to method name
- move
@Unroll
to class - why
@Unroll
pattern is sometimes better than embedding it in method name
- can be any
- data table
- start with calculations in spec
- don't use
old
… yet - move calculated values to
where
block mixed with table
Where…
where:
coins | products
[Quarter] * 4 | [Slurm]
[Quarter] * 3 + [Dime] * 10 | [ChocolateSaltyBalls, Slurm]
totalInserted = coins.sum { it.value }
totalSpent = products.sum { it.price }
Discuss…
- even when not iterating
where
blocks can clarify test inputs and outputs
- 1st test:
- asserting invoked
- show expectation failing
- mocks are lenient - add extra coin return to CUT & test still passes
- asserting no further invocations
- wildcard params (show variations)
- method matching; regex, wildcard
- all mocks wildcard:
0 * _._
…0 * _
- asserting invoked
- 2nd test:
- asserting never invoked
- 3rd test:
- stubs
- lenient not strict; stubs just work
- show explicit stub declaration
given: hardware.returnCoin(Penny)
- 4th test:
- grouping assertions using
with
- grouping assertions using
Discuss…
- explain
Stub
- for clarity only; you can stub with a
Mock
- for clarity only; you can stub with a
- explain
Spy
- evil but helpful especially in legacy
- must be a class not an interface
- can act as "partial" mocks
- Limitations
- cannot do static or partial mocking
- could be argued requiring those is a design smell anyway
old
- clarity of assertion
- less brittle
- action closures
- mocks throwing exceptions
- mocks accessing arguments
- exception handling using
thrown
@Stepwise
- adds clarity
- dangers; brittle (people add inappropriate stuff), violation of atomicity (stuff leaks from one test to next), slower to debug
@Shared
- initialization of
@Shared
variables only happens once (show non-shared & test failing) - mocks cannot be
@Shared
- initialization of
- Just show use of
BlockingVariable
- Interaction closure on
Mock
declaration - Multiple
then
blocks to enforce interaction order - Returning things from mocks
- sequential return values
- Global mocks
- Different default returns from stubs