I have a class:
class SomeDao {
this: support =>
def get(id:Long): Option[SomeDto] = {
support.sprocCall(SomeDto.fromResultSet, SomeDao.getSproc, id)
}
}
SomeDto.fromResultSet is actually a Function1 [WrapperResultSet, SomeDto].
Is it possible to verify that support.sprocCall has been called with the correct function as the first parameter?
-
Mockito can do this.Daenyth– Daenyth2015年05月29日 17:55:48 +00:00Commented May 29, 2015 at 17:55
-
Similar questiongoralph– goralph2015年05月29日 19:16:00 +00:00Commented May 29, 2015 at 19:16
-
@Daenyth, we were playing with mockitosugar and the best we could do was figure out how to prove that the parameter SomeDto.fromResultSet was called with a Function1 (instead of just anyObject).Brian Kessler– Brian Kessler2015年05月29日 19:41:00 +00:00Commented May 29, 2015 at 19:41
-
@Michael Kendra, thanks for the response but there is a significant difference. In this instance, we want to verify that the first argument is a particular function and not just a particular value.Brian Kessler– Brian Kessler2015年05月29日 19:43:22 +00:00Commented May 29, 2015 at 19:43
2 Answers 2
This question has two parts. First, you need to test what was the argument to a method invocation inside your class. Second, you want to do some form of function equality.
As mentioned in the comments, to solve the first problem you can use Mockito. See the example below on how to do that using ArgumentCaptor.
Now, the second part is more complex. See the answer here about function equality. In the code example below, I forced the functions func1 and func2 to be instantiated and stored them into val func_a and val func_b respectively. I then used the two val throughout my test code. If doing something similar is not possible during your test, then I am afraid there is NO good way of achieving what you need.
To better show the problem of function equality in Scala, I added the last two lines in the example.
import org.mockito.ArgumentCaptor
import org.mockito.Matchers._
import org.mockito.Mockito._
object ToyExample extends App {
// A toy class
class TargetClass {
def add(str: String, func: String => Long, j: Long): Long = func(str) + j
}
// These are the two functions we can use
def func1(g: String): Long = g.toLong
def func2(g: String): Long = g.toLong * 2
// Here is an example of using the TargetClass
val actualInstance = new TargetClass
println( actualInstance.add("12", ToyExample.func1, 2) ) // Prints 14
// Here is with the mock
val mockedSomeDao = mock(classOf[TargetClass])
val func_a = func1 _
val func_b = func2 _
// ... use the mocked object to do what you want
mockedSomeDao.add("12", func_a, 2)
// Now verify that the argument is the right one
val argument = ArgumentCaptor.forClass(classOf[(String) => Long])
verify(mockedSomeDao, atLeastOnce()).add(anyString(), argument.capture(), anyLong())
if( argument.getValue eq func_a ) {
println("Func 1") // This one gets called
} else if (argument.getValue eq func_b) {
println("Func 2")
}
println( func_a eq func_a) // Prints "true"
println( func1 _ eq func1 _) // Prints "false"!
}
Comments
You're treading very close to the problem of determining if two functions are equal. That particular problem has been covered many times on SO, such as How to compare Scala function values for equality I believe your question is just a less general form of that question. If so, the answer is that you can't do it for good reasons founded in theory.