I am trying to test the overridden toString() in groovy (I know it is trivial but that is what you get after reading kent beck's TDD book).
I assertSame on the expected string and the actual
Here is the code block:
#Test void testToString(){
def study = new Study(identifier:"default-study", OID:"S_DEFAULTS1", name:"Default Study")
def expected = "org.foo.oc.model.bar(OID:S_DEFAULTS1, name:Default Study, identifier:default-study)"
assertSame "Should be equal", expected, study.toString()
}
Here is the stack trace for the failed test:
junit.framework.AssertionFailedError: Should be equal expected same:org.foo.oc.model.bar(OID:S_DEFAULTS1, name:Default Study, identifier:default-study) was not:org.foo.oc.model.bar(OID:S_DEFAULTS1, name:Default Study, identifier:default-study)
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotSame(Assert.java:273)
at junit.framework.Assert.assertSame(Assert.java:236)
Just to add that assertEquals works well with the same parameters.
I know it is no biggie but I want to understand why it fails.
Thanks
Why aren't you using assertEquals which uses .equals()? assertSame compares object references (== operator). Even though the strings are the same, they are two different objects, hence the assertion is failing.
UPDATE: This is a very common mistake in Java: String.equals() and == operator work differently. This has been discussed several times:
How do I compare strings in Java?
Java String.equals versus ==
Difference between Equals/equals and == operator?
I know you are using Groovy which does not suffer this problem, but JUnit is written in Java and behaves according to the rules above.
UPDATE: actually, your string are different:
org.foo.oc.model.bar(OID:S_DEFAULTS1, name:Default Study, identifier:default-study)
org.foo.oc.model.bar(OID:S_DEFAULTS1, name:Default Study, identifier:default-study)
Your original uses lowercase d in "default Study" but your expected string does not.
EDIT: when comparing strings you should always use equals() rather than comparing references. Two strings that pass the equals() test may or may not also be the same object.
BTW, in Groovy == is the same as equals().
Related
I have a kotlin function of this form in an interface:
fun foo(bar: String, vararg baz: Pair<String, ByteArray>):Boolean
Using Mockito to mock this interface, how do I verify that this function was called with no Pairs?
It doesn't work leaving the second matcher off, because then Mockito complains that it needs two matchers.
Using any any*() matcher, including anyVararg(), fails because of typing.
A non-answer to give some inspiration:
Keep in mind that Mockito doesn't know or care what you are writing in some Kotlin source code file.
Mockito only deals with the compiled byte code. In other words: Mockito looks into the final classfile; created by the kotlin compiler.
Thus: your first stop should be javap to disassemble the class file that contains that method definition. You check the signature of the method there; and that should tell you how to specify correct argument matchers to Mockito.
And just another idea: java varargs translate arrays. So "no" args means: an empty array. So you probably want to match specifically on something like empty array of Pairs.
I have code like that:
def a1 = [[1],[2],[3]]
def a2 = [[2],[3],[4]]
a1.intersect(a2)
and as result got:
[]
After some time of research i found out that elements of lists must be instance of Comparable. In DefaultGroovyMethods we can see implementation of intersect method. First thing i noted was the collection (TreeSet) used for checking existence of objects in one of our lists (btw. if HashSet used it worked fine).
I checked the NumberAwareComparator there are two options for checking in compareTo method. The first is the delegation of comparison to another class (eaten exception ?!) and the second is hashCode checking.
The first option DefaultTypeTransformation explained us the behavior.
We can see that only allowed object to be compare are Comparable in other case we got exception eaten later.
My question is why is it like that? There is lack of information in documentation (or am i wrong?) about it. Did i missed something?
Can't find it documented.
Feels like a great pull request contribution to the project on github with a change to the existing documentation/javadoc to make this more explicit?
The elements have to be comparable, as otherwise you can't compare them to check for an intersection, but you're right the documentation isn't explicit.
You could write your own implementation like so:
Collection.metaClass.equalityIntersect = { Collection other ->
delegate.findAll { a -> other.find { it == a } }
}
So that a1.equalityIntersect(a2) == [[2], [3]]
This behavior has been introduced somewhere down the line - haven't pin-pointed it, maybe 2.4.2 or 2.4.2 as per this commit. It used to work in 2.2.1 and 2.4.0 and is broken on 2.4.6... but it's fixed in 2.4.7.
$ groovy -v
Groovy Version: 2.4.7 JVM: 1.8.0_92 Vendor: Oracle Corporation OS: Mac OS X
$ groovy intersect.groovy
[[2], [3]]
How can such breaking change roll out to a release is a mystery to me. Lack of testing?
I have a variable of this type:XSSFSheet sheet (I'm using apache-poi to read from Excel).
In the simple groovy console I can do sheet[4][5] to access a certain cell by coordinates. When I try the same thing in IntelliJ, it gives me the exception that
No signature of method: org.apache.poi.xssf.usermodel.XSSFSheet.getAt() is applicable for argument types: (java.lang.Integer) values: [0]
Possible solutions: getAt(java.lang.String), getRow(int), putAt(java.lang.String, java.lang.Object), wait(), last(), first()
I looked in the reference and indeed, XSSFSheet can't be indexed by an int. But why then it is possible in the simple groovy console that comes with it? Can I do the same in IntelliJ?
This is old, and I'm only answering because I was wondering the same thing you asked in your last comment and found the answer trying to understand.
As you mention in your last comment, the subscript operator in groovy translates to the getAt() method, and as you say, the XSSFSheet class doesn't have such a method in java.
Since it can indeed be called from groovy, it does exist somewhere. With a bit of metaprogramming, we get the following:
def getAt = org.apache.poi.xssf.usermodel.XSSFRow.metaClass.getMetaMethod("getAt", [java.lang.Integer] as Class[])
println getAt
org.codehaus.groovy.runtime.dgm$240#e7edb54[name: getAt params: [int] returns: class java.lang.Object owner: interface java.lang.Iterable]
Which means it comes from the Iterable interface. And still, this is not true in java. But groovy adds many methods to standard java classes, and indeed we can see here that it adds a getAt() method to Iterable.
This doesn't answer your original question (why doesn't it work in your IntelliJ ? it should and it does here), but it answers a question in the comments. I would have posted it there, but I lack reputation.
My question is regarding the property count in the matcher class in groovy. Following is an example:
import java.util.regex.Matcher
def p= /[a-z]*/
Matcher m= "abc" =~ p
println m.count
As you can see, Groovy actually uses the Matcher class in Java. According to javadoc, Matcher doesn't have any count property. We have to use loops to count manually in Java development for pattern matching. How can groovy do this? Is it documented somewhere?
Thanks,
A good start for this is Groovy Backstage and especially Groovy Method Invocation. Basically the classes get a metaClass augmented with a common set of tools (e.g. DefaultGroovyMethods (see below) for Object). On method invocation, groovy takes this into account for "what is there". count for Matcher is already some more special case, something much more common used on Object is e.g. println.
If you are interested only in the functionality itself you can check the GDK. E.g. for Matcher.getCount().
If you are interested how it is actually implemented, then a good start is always DefaultGroovyMethods or the descendants of DefaultGroovyMethodsSupport in general. So following this for Matcher.getCount() leeds to https://github.com/groovy/groovy-core/blob/master/src/main/org/codehaus/groovy/runtime/StringGroovyMethods.java#L1508.
If you run the following Groovy code, the assertion passes
def foo(a, b) {
a + b
}
assert 'aaabbb' == foo(['aaa', 'bbb'])
This suggests that if a method is called with a List parameter that contains X elements, then the List will be spread and a method with X arguments will be invoked.
Of course, this will only happen if there isn't a method defined with a single parameter of type List (or ancestor thereof).
I only discovered this quite recently when reading another SO Groovy answer. I've never seen it mentioned in the Groovy docs, release notes, or books. Is it a hidden feature, a bug, or just something I've missed?
Going to be removed in Groovy 2 apparently:
http://groovy.329449.n5.nabble.com/removing-features-in-Groovy-2-td4422494.html
JT's first on the to-remove list and it seems everyone (with clout) on Groovy User agrees.