I can't understand how I can setup a parametrized test with spock for void methods.
This is my simple test case for a linked list:
#Unroll
def "should delete the element #key and set the list size to #listSize"(key, listSize) {
given:
list.insert(6)
list.insert(12)
list.insert(33)
expect:
def deletedKey = list.delete(key)
list.size() == listSize
where:
key || listSize
6 || 2
12 || 2
33 || 2
99 || 3
}
The method delete() is a void method, but if I'm not getting explicitly a return value then the test is failing.
This is actually working:
expect:
def deletedKey = list.delete(key)
list.size() == listSize
while this doesn't:
expect:
list.delete(key)
list.size() == listSize
The test report complains about a null
Condition not satisfied:
list.delete(key)
| | |
| null 12
com.github.carlomicieli.dst.LinkedList#5c533a2
How can I manage this situation? I would like to test the results of deletion checking the list state after the deletion method has been called.
Thanks,
Carlo
Does it work if you use when and then rather than expect?
#Unroll
def "should delete the element #key and set the list size to #listSize"(key, listSize) {
given:
list.insert(6)
list.insert(12)
list.insert(33)
when:
list.delete(key)
then:
list.size() == listSize
where:
key || listSize
6 || 2
12 || 2
33 || 2
99 || 3
}
Related
I am building a string in this way:
def presentationType = "${feedDisplayType}, ${moduleType}, ${cellType}"
What happens is that sometimes the variables has null values, and the resulting string is showing this null values, I have to avoid show null values.
I want to know if there is some way to remove this possible null values in the string or avoid add this when they will be presented.
I know that it is possible and more easy to do with arrays, but I want to do it with strings in a more direct way.
Thanks for any help in advance.
There are 3 options:
1. GString interpolation
def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
2. Using StringBuilder
def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
sb.append(feedDisplayType)
sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
sb.append(moduleType)
sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
sb.append(cellType)
}
def presentationType = sb.toString()
3. Joining a list with , as a delimiter
def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
Benchmark
Before going into conclusion let's benchmark all 3 methods using GBench tool:
#Grab(group='org.gperfutils', module='gbench', version='0.4.3-groovy-2.4')
def feedDisplayType = 'test'
def moduleType = null
def cellType = ''
def r = benchmark {
'GString method' {
def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
}
'StringBuilder method' {
def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
sb.append(feedDisplayType)
sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
sb.append(moduleType)
sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
sb.append(cellType)
}
def presentationType = sb.toString()
}
'Join list method' {
def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
}
}
r.prettyPrint()
Output
Environment
===========
* Groovy: 2.4.12
* JVM: OpenJDK 64-Bit Server VM (25.171-b10, Oracle Corporation)
* JRE: 1.8.0_171
* Total Memory: 236 MB
* Maximum Memory: 3497 MB
* OS: Linux (4.16.5-200.fc27.x86_64, amd64)
Options
=======
* Warm Up: Auto (- 60 sec)
* CPU Time Measurement: On
user system cpu real
GString method 265 2 267 268
StringBuilder method 72 4 76 77
Join list method 484 3 487 495
Conclusion
If you aim towards highest throughput, StringBuilder method is the best one (77 nanoseconds mean time).
GString method is a few times slower than StringBuilder and it is much less readable due to all condition statements inside a single GString. It is also pretty error prone - it's easy to make a mistake when interpolating String in this case.
Joining list method is the slowest one (only 2 times slower approximately than GString method), but it is the cleanest one. And it is still pretty fast - 495 nanoseconds is acceptable in most cases. Of course optimization depends on specific use case - if you have to execute this part of code million times per second, then using StringBuilder instead makes much more sense.
Benchmark corner cases
To make this example complete let's also take a look at corner cases in benchmarking. We use the same code with different input.
Input:
def feedDisplayType = 'lorem ipsum'
def moduleType = 'dolor sit amet'
def cellType = '123456789'
Output:
user system cpu real
GString method 387 1 388 390
StringBuilder method 170 0 170 175
Join list method 847 6 853 859
Input:
def feedDisplayType = ''
def moduleType = ''
def cellType = ''
Output:
user system cpu real
GString method 237 5 242 242
StringBuilder method 44 0 44 44
Join list method 441 0 441 446
Edit: This answer has been changed as there is a requirement to not print "," for null terms.
Consider:
def feedDisplayType = 'abc'
def moduleType = null
def cellType = 'ijk'
def f = { s, isLast = false ->
def token = s ?: ''
def seperator = (!s || isLast) ? '' : ','
"${token}${seperator}"
}
def presentationType = "${f feedDisplayType}${f moduleType}${f cellType,true}"
assert 'abc,ijk' == presentationType
Note that in function calls, parens are optional in Groovy so ${f x} is equivalent to ${f(x)}. f was originally field in an earlier version, but I've shortened it for brevity.
I have two collections of different types - eg. Fruit and Vegetable.
Now in spock I assert contents of those collections in one of the following ways:
fruits.size() == vegetables.size()
for (int i = 0; i < fruits.size(); i++) {
assert fruits[i].name == vegetables[i].name
assert fruits[i].active == vegetables[i].enabled
}
Is there any better way to compare such collections?
You can utilize Groovy's spread operator to extract list of values and compare those lists. Consider following example:
class Fruit {
String name
boolean active
}
class Vegetable {
String name
boolean enabled
}
def fruits = [new Fruit(name: 'Apple', active: false), new Fruit(name: 'Tomato', active: true)]
def vegetables = [new Vegetable(name: 'Apple', enabled: false), new Vegetable(name: 'Tomato', enabled: false)]
assert fruits.name == vegetables.name
assert fruits.active == vegetables.enabled
First assertion passes, because:
assert ['Apple', 'Tomato'] == ['Apple', 'Tomato']
However second assertion fails, because:
assert fruits.active == vegetables.enabled
| | | | |
| | | | [false, false]
| | | [Vegetable#5b8dfcc1, Vegetable#2f9f7dcf]
| | false
| [false, true]
[Fruit#747ddf94, Fruit#35e2d654]
In this case you don't have to compare if both lists have the same size and also order of objects matters. The only downside is that values you extract to lists have to be comparable - otherwise it will compare references to objects.
Finally, your Spock test could look like this:
def "comparing fruits and vegetales"() {
when:
def fruits = initializeFruits()
def vegetables = initializeVegetables()
then:
fruits.name == vegetables.names
and:
fruits.active == vegetables.enabled
}
I have a situation where I have to write a code for a groovy script which is not written inside a class . Its just a plain groovy script. For some reason I can't show the actual code .But it would simply like this:
def var = 10
return var
You can create an object of the class and call run() method on it. This will instantiate the class and run the method in it.
You do not have to write tests specially in the case that you mentioned.
Use in-built assert for the same.
def var = 10
var++
assert 11 == var, 'Value mismatch for var'
One style is to write micro-tests inline, using the assert feature (as mentioned elsewhere):
def reverseString = { s ->
s?.reverse()
}
// test_reverseString
assert 'cba' == reverseString('abc')
assert '' == reverseString('')
assert null == reverseString(null)
def sumList = { list ->
(list == null) ? 0 :
(list.isEmpty()) ? 0 :
list.sum()
}
// test_sumList
assert 6 == sumList([1,2,3])
assert 0 == sumList([])
assert 0 == sumList(null)
// ---- main
println reverseString('esrever')
println sumList([1,2,3,4])
It is relatively easy to modify this code so that only the tests execute (e.g. based on a command-line argument).
I am working on a script to collect field names (dialogPartyASelection_* && dialogPartyBSelection_*) and then compare the two values to see check if they match. The full list(selections)of fields is being broken down into 'groups' before comparison. I can break out certain parts (IE, comparing the two field values via iteration) and test successfully, however when bringing everything together the script doesn't seem to compare correctly. I may be approaching this/setting myself up to do this wrong, (have started to toy with creating a map, with party A as the key with party B as value).
Snippet of code:
// Test Variables
PartyBSelection_Propertieshamster = 'Accepted'
PartyBSelection_Propertieszembra = 'Agreed'
PartyBSelection_Propertiesdogs = 'Agreed'
PartyBSelection_Propertiescats = 'Decision taken'
PartyASelection_Propertieshamster = 'Accepted'
PartyASelection_Propertieszembra = 'Agreed'
PartyASelection_Propertiesdogs = 'Agreed'
PartyASelection_Propertiescats = 'Decision taken'
// example of selections(there are lots of entries for A/B party) = ['dialogPartyBSelection_Communication','dialogPartyASelection_Housing','dialogPartyASelection_Income','PartyASelection_Properties']
def selectedGroup = { s -> selections.findAll { it.contains s}} // for pulling groups of questions from list
def isAgreed = { a, b -> (a in ['Agreed', 'Decision taken','Accepted'] && b in ['Agreed', 'Decision taken','Accepted']) } // for comparing values
for(questions in selectedGroup("Properties")){
{k -> percentCompleteProperties += isAgreed("PartyASelection_${k}", "PartyBSelection_${k}")? 1 : 0}
println questions
println percentCompleteProperties
}
Current output:
PartyBSelection_Propertiescats
0
PartyBSelection_Propertieshamster
0
PartyBSelection_Propertiesdogs
0
PartyBSelection_Propertieshamster
0
PartyASelection_Propertiescats
0
PartyASelection_Propertieshamster
0
PartyASelection_Propertiesdogs
0
PartyASelection_Propertieshamster
0
This is sample code.
but i had changed test data etc.
please check whether this logic is correct for your case.
// Test Variables
def testVariables = [
'PartyBSelection_PropertiesAssets':'Accepted',
'PartyBSelection_PropertiesDebts': 'Agreed',
'PartyBSelection_PropertiesMoney': 'Agreed',
'PartyBSelection_PropertiesSpecialGoods':'Decision taken',
'PartyASelection_PropertiesAssets':'Accepted',
'PartyASelection_PropertiesDebts':'Agreed',
'PartyASelection_PropertiesMoney':'Agreed',
'PartyASelection_PropertiesSpecialGoods':'Decision taken'
]
List<String> selections= [
'PropertiesAssets',
'PropertiesDebts',
'PropertiesMoney',
'PropertiesSpecialGoods',
'PropertiesAssets',
'PropertiesDebts',
'PropertiesMoney',
'PropertiesSpecialGoods'
]
def selectedGroup = { s -> selections.findAll { it.contains s}}
List<String> okLabels = ['Agreed', 'Decision taken','Accepted']
def isAgreed = {a, b ->
(testVariables[a] in okLabels && testVariables[b] in okLabels)
}
List<Map<String, Integer>> result = selectedGroup("Properties").collect {String question ->
[(question) : isAgreed("PartyASelection_${question}", "PartyBSelection_${question}")? 1 : 0 ]
}
assert result == [
['PropertiesAssets':1],
['PropertiesDebts':1],
['PropertiesMoney':1],
['PropertiesSpecialGoods':1],
['PropertiesAssets':1],
['PropertiesDebts':1],
['PropertiesMoney':1],
['PropertiesSpecialGoods':1]
]
Other way
def r = [:]
def questionsCount = selectedGroup("Properties").size()
selectedGroup("Properties").eachWithIndex {String question, Integer i ->
println "question:${question}(${i+1}/${questionsCount})"
r.put(question,isAgreed("PartyASelection_${question}", "PartyBSelection_${question}")? 1 : 0 )
}
// This version includes all records in to the one map.
// Also, a record that is duplicated (as key) is overwritten.
r == [PropertiesAssets:1, PropertiesDebts:1, PropertiesMoney:1, PropertiesSpecialGoods:1]
then output:
question:PropertiesAssets(1/8)
question:PropertiesDebts(2/8)
question:PropertiesMoney(3/8)
question:PropertiesSpecialGoods(4/8)
question:PropertiesAssets(5/8)
question:PropertiesDebts(6/8)
question:PropertiesMoney(7/8)
question:PropertiesSpecialGoods(8/8)
I have a problem to get last two digit from a string.
example :
String texter = "5793231309"
how to get '09' ?
so when Iprintln "texter : "+texter.
It will be Groovy<<09
I try split but it not successful ?
Use this to split your first String:
static main(args) {
String texter = "5793231309"
String texter2 = texter[-2..-1]
println(texter2)
}
Here's a one liner that's also a safe alternative:
assert "5793231309".reverse().take(2).reverse() == "09"
In groovy you can substring via negative indices.
String last2 = texter[-2..-1] // Last 2 symbols
Its an analogue of substring, and it uses Ranges.
http://groovy.codehaus.org/Collections see 'Slicing with the subscript operator'
Inspired by tim_yates:
It may be safer to use some function, to extract last n characters, as tim suggested. But I think his solution, with regexp is a big overhead, and may be hard to understand by novices.
There is an easier and faster way to do this, using size() check, and then range substring:
def lastN(String input, int n){
return n > input?.size() ? null : n ? input[-n..-1] : ''
}
assert lastN("Hello", 2) == 'lo'
assert lastN("Hello", 3) == 'llo'
assert lastN("Hello", 0) == ''
assert lastN("Hello", 13) == null
assert lastN(null, 3) == null
Be careful though, if your unit is less than 2 characters long, s[ -2..-1 ] will fail.
Might be better to do:
String lastN( String input, int n ) {
input == null ?
null :
( input =~ /^.+(\S{$n})$/ ).with { m -> m.matches() ?
m[ 0 ][ 1 ] :
null }
}
assert lastN( "5793231309", 2 ) == '09'
assert lastN( "5793231309", 3 ) == '309'
assert lastN( "5793231309", 0 ) == ''
assert lastN( '', 2 ) == null
assert lastN( null, 2 ) == null
Or:
String lastN( String input, int n ) {
if( input == null || input.length() < n ) null
else if( n == 0 ) ''
else input[ -n..-1 ]
}
assert lastN( "5793231309", 2 ) == '09'
assert lastN( "5793231309", 3 ) == '309'
assert lastN( "5793231309", 0 ) == ''
assert lastN( '', 2 ) == null
assert lastN( null, 2 ) == null
The most readable solution is probably just to drop() all but the last two characters:
def texter = "5793231309"
println texter.drop(texter.size() - 2) //result: "09"
Or as a reusable closure:
def lastTwo = { it.drop(it.size() - 2) }
println lastTwo("ABC") //result: "BC"
println lastTwo("AB") //result: "AB"
println lastTwo("A") //result: "A" (no exception thrown)
println lastTwo("") //result: "" (no exception thrown)
Fiddle with the code:
https://groovyconsole.appspot.com/script/5768158526832640
More examples of Groovy goodness:
http://mrhaki.blogspot.com/2011/09/groovy-goodness-take-and-drop-items.html
Another safe alternative using size() and substring() methods:
s?.size() < 2 ? s : s.substring(s.size() - 2)
Note the above takes care of nulls and strings that are less than two characters long.
In Java use
String texter = "5793231309";
String val=texter.substring(texter.length()-2,texter.length());
System.out.println("val-->"+val);
In Groovy you don’t need the above stuff just,
String value= texter[-2..-1]