Checking call arguments when method has parameters with default values

116 views
Skip to first unread message

AlexVa

unread,
Jul 14, 2015, 12:55:00 PM7/14/15
to specs2...@googlegroups.com
Hi,

Story
I have a mock for a class with method having parameters with default values. My code calling it with only the mandatory params. In my test I want to verify that the mocked object has been called correctly. 

Issue
In the test the statement "there was one(a).foo(12)" always passes without respect to the parameter value, that is the actual code in the code could be a.foo(100) but this line passes.

Question
How should such code be tested using specs2? The workaround I used is to test all the parameters, that is: there was one(a).foo(be_===(12), any[Int])

Example

class A {
  def foo(x: Int, y: Int = 10) = x * y
}

class B(a: A) {
  def bar(x: Int) = a.foo(x)
}


class MyTest extends SpecificationWithJUnit with Mockito {
  trait ctx extends Scope {
    val a = mock[A]
    val aut = new B(a)
  }

  "passes (works wrong!)" in new ctx {
    b.bar(11)

    got {
      one(a).foo(12)
    }
  }

  "fails (works correct)" in new ctx {
    b.bar(11)

    got {
      one(a).foo(be_===(12),any[Int])
    }
  }
}

Thanks,
Alex

etorreborre

unread,
Jul 14, 2015, 6:57:59 PM7/14/15
to specs2...@googlegroups.com, alexa...@wix.com
Hi Alex,

I'm afraid that this is a problem with how Mockito deals with the encoding of default arguments when using Scala.

If you look at the java-like code for the generated default arguments you can see:

public class B
{
  private final A a;

  public int bar(int x)
  {
    return this.a.foo(x, this.a.foo$default$2());
  }

  public B(A a)
  {
  }
}

public class A
{
  public int foo(int x, int y)
  {
    return x * y; }
 
  public int foo$default$2() { return 10; }

}

When Mockito tries to intercept the call for `foo` it actually intercepts the call for foo$default$2() and passes it an empty array of arguments to check, which always succeeds. I don't think I can really fix this in specs2. I've already done some hacky work for call-by-name arguments but I don't know how to fix that one. Maybe your only alternative here is to use ScalaMock instead.

Eric.

AlexVa

unread,
Jul 15, 2015, 2:58:21 AM7/15/15
to specs2...@googlegroups.com, alexa...@wix.com
I see. 
Thanks for the answer
Alex
Reply all
Reply to author
Forward
0 new messages