0

Here is an example of what I try to achieve. Stub always retuns null, but if I change Array(1L) to * it works. It seems there is a problem with array arguments.

trait Repo {
    def getState(IDs: Array[Long]): String
}


"test" should "pass" in {
    val repo = stub[Repo]
    (repo.getState _).when(Array(1L)).returns("OK")
    val result = repo.getState(Array(1L))
    assert(result == "OK")
}
gorros
  • 1,411
  • 1
  • 18
  • 29
  • https://stackoverflow.com/questions/2481149/why-does-array0-1-2-array0-1-2-not-return-the-expected-result Array(1L) == Array(1L) -> false – Ivan Jul 10 '17 at 15:22

1 Answers1

2

See this post:

Why doesn't Array's == function return true for Array(1,2) == Array(1,2)?

ScalaMock is working fine, but Array equality prevents your expected arg from matching your actual arg.

e.g. this works:

 "test" should "pass" in {
   val repo = stub[Repo]
   val a = Array(1L)
   (repo.getState _).when(a).returns("OK")
   val result = repo.getState(a)
   assert(result == "OK")
 }

However there is also a way to add a custom matcher(defined in org.scalamock.matchers.ArgThat):

 "test" should "pass" in {
   val repo = stub[Repo]
   (repo.getState _).when(argThat[Array[_]] {
     case Array(1L) => true
     case _ => false
   }).returns("OK")
   val result = repo.getState(Array(1L))
   assert(result == "OK")
 }

Update - example for mixed wildcards, literals, argThat:

 trait Repo {
   def getState(foo: String, bar: Int, IDs: Array[Long]): String
 }

 "test" should "pass" in {
   val repo = stub[Repo]
   (repo.getState _).when(*, 42, argThat[Array[_]] {
     case Array(1L) => true
     case _ => false
   }).returns("OK")
   val result = repo.getState("banana", 42, Array(1L))
   assert(result == "OK")
 }
Philipp
  • 967
  • 6
  • 16
  • I known that arrays do not compare as expected. But I hoped that was not the reason. Since Mockito framework worked as expected. – gorros Jul 10 '17 at 19:11
  • @gorros I've improved the answer above, maybe you like the `argThat` matcher syntax – Philipp Jul 10 '17 at 20:25
  • Thanks for the update, but in my real code I have more than one arguments in when, and some are wildcards, and argsThat does not work with them, so I probably will stick to Mockito. – gorros Jul 11 '17 at 05:27
  • I don't understand that last comment. the when call takes multiple parameters if your API does, so you can use wildcards for some of them, literals for non-Array types, and the argThat for Array, or a combination of all that? – Philipp Jul 12 '17 at 07:02
  • My first argument is an array and then I use wildcards, and it did not work. – gorros Jul 12 '17 at 07:31
  • So to the example above, is it just the order of arguments that is different? Think it is a bug that should be looked at? – Philipp Jul 12 '17 at 16:50
  • As final solutions to avoid such problems I decided to go with `List`s – gorros Aug 03 '17 at 15:29