Create a gist now

Instantly share code, notes, and snippets.

memoizing object creation during spock test
import groovy.transform.Immutable
@Immutable
class User {
UUID id
String fullName
int age
}
class VeryComplexFilter {
int ageThreshold = 40
List<User> lifeStartsAt40(List<User> input) {
input.findAll { it.age >= ageThreshold }.sort { it.age }
}
}
import spock.lang.Specification
import spock.lang.Unroll
//@GrabResolver('https://oss.sonatype.org/content/groups/public')
//@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
//@GrabConfig( systemClassLoader=true )
class UUIDsClutterYourTests extends Specification {
@Unroll
def "from users with age #inputUsersAge, #resultSize users are kept"() {
given:
def underTest = new VeryComplexFilter()
when:
def result = underTest.lifeStartsAt40(input.collect {
new User(id: UUID.fromString(it[0]), age: it[1])
})
then:
result*.id == expectedResult.collect { UUID.fromString(it) }
where:
input || expectedResult
[["40288045-4BA8-CB2E-014B-A8CB2E780000", 35]] || []
[["40288045-4BA8-CB2E-014B-A8CBA1330002", 41]] || ["40288045-4BA8-CB2E-014B-A8CBA1330002"]
[["40288045-4BA8-CB2E-014B-A8CB2E780000", 35],
["40288045-4BA8-CB2E-014B-B0C80EDB0003", 52],
["40402880-454B-A8CB-2E01-4BB0D5051F00", 15],
["40288045-4BA8-CB2E-014B-B0D5CB820005", 79],
["40288045-4BA8-CB2E-014B-A8CBA1330002", 41]] || ["40288045-4BA8-CB2E-014B-A8CBA1330002",
"40288045-4BA8-CB2E-014B-B0C80EDB0003",
"40288045-4BA8-CB2E-014B-B0D5CB820005"]
inputUsersAge = input*.get(1)
resultSize = expectedResult.size()
}
static def uuids = (1..10).collect { UUID.randomUUID().toString() }
@Unroll
def "with predefined uuids, from users with age #inputUsersAge, #resultSize users are kept"() {
given:
def underTest = new VeryComplexFilter()
when:
def result = underTest.lifeStartsAt40(input.collect {
new User(id: UUID.fromString(it[0]), age: it[1])
})
then:
result*.id == expectedResult.collect { UUID.fromString(it) }
where:
input || expectedResult
[[uuids[0], 35]] || []
[[uuids[1], 41]] || [uuids[1]]
[[uuids[0], 35], [uuids[3], 52], [uuids[4], 15], [uuids[5], 79], [uuids[1], 41]] || [uuids[1], uuids[3], uuids[5]]
inputUsersAge = input*.get(1)
resultSize = expectedResult.size()
}
Closure<?> uuid = { _ ->
return UUID.randomUUID()
}.memoize() //remember what symbol we mapped to the UUID
@Unroll
def "with memoized uuids, from users with age #inputUsersAge, #resultSize users are kept"() {
given:
def underTest = new VeryComplexFilter()
when:
def result = underTest.lifeStartsAt40(input.collect {
def (idChar, age) = it.split('-')
new User(id: uuid.call(idChar), age: age as int)
})
then:
result*.id == expectedResult.collect { uuid.call(it) }
where:
input || expectedResult
["a-35"] || ''
["b-41"] || 'b'
["a-35", "c-52", "d-15", "e-79", "b-41"] || 'bce'
inputUsersAge = input.collect { it.split('-').last() }
resultSize = expectedResult.size()
}
Closure<?> user = { String idAndAge ->
def (_, age) = idAndAge.split('-')
new User(id: UUID.randomUUID(), age: age as int)
}.memoize() //remember what symbol we mapped to the UUID
@Unroll
def "with memoized users, from users with age #inputUsersAge, #resultSize users are kept"() {
given:
def underTest = new VeryComplexFilter()
when:
def result = underTest.lifeStartsAt40(input.collect { user.call(it) })
then:
result == expectedResult.collect { user.call(it) }
where:
input || expectedResult
["a-35"] || []
["b-41"] || ['b-41']
["a-35", "c-52", "d-15", "e-79", "b-41"] || ['b-41','c-52', 'e-79']
inputUsersAge = input.collect { it.split('-').last() }
resultSize = expectedResult.size()
}
}
import spock.lang.Specification
import static TestUtils.*
class RememberTest extends Specification {
def "remembering symbols to object creation"() {
given:
remember('complex', { createComplexObject() })
expect:
id('a') instanceof UUID
id('a') == id('a')
id('a') != id('abc')
user('a-52') instanceof User
user('a-52').age == 52
user('a-52') == user('a-52')
user('a-52') != id('a')
recall('complex', 'a') == recall('complex', 'a')
recall('complex', 'a') != recall('complex', 'b')
recall('complex', 'a') != recall('complex', 'abc')
recall('complex', 'abc') == recall('complex', 'abc')
}
def createComplexObject() {
return (1..20).collect { UUID.randomUUID() }.groupBy { it.toString().toList().last() }
}
}
class TestUtils {
private TestUtils() {}
/**
* knows how to create objects given a creatorId
*/
private static final Map<Object, Closure<?>> creatorRegistry = [
(UUID): { UUID.randomUUID() },
(User): { idAndAge ->
def (_, age) = idAndAge.split('-')
new User(id: UUID.randomUUID(), age: age as int)
}
]
/**
* remembers what object was created given the symbol and the creatorId
*/
private static Closure<?> remembers = { String symbol, Object creatorId ->
def creator = creatorRegistry[creatorId]
assert creator
return creator.call(symbol)
}.memoize() //remember what symbol we mapped to what created object
/**
* Registers a creator for a given creatorId
* @param creatorId
* @param creator
*/
static <T> void remember(def creatorId, Closure<T> creator) {
assert creatorId
assert creator
creatorRegistry << [(creatorId): creator]
}
/**
* Recall the object matching the creatorId with the given symbol
* @param creatorId
* @param symbol
* @return
*/
static <T> T recall(def creatorId, String symbol) {
assert symbol
assert creatorId
return remembers.call(symbol, creatorId) as T
}
/**
* Generates the same UUID for the same input
* @param c
* @return
*/
static UUID id(String c) {
recall(UUID, c)
}
/**
* Generates the same User for the same input
* @param idAndAge
* @return
*/
static User user(String idAndAge) {
recall(User, idAndAge)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment