Skip to content

Match failure with varargs and multiple parameter lists #69

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
githorse opened this issue Jan 4, 2019 · 5 comments
Closed

Match failure with varargs and multiple parameter lists #69

githorse opened this issue Jan 4, 2019 · 5 comments

Comments

@githorse
Copy link

githorse commented Jan 4, 2019

Mocking with varargs works as expected:

trait FooWithVarArg {
  def bar(bells: String*) 
}

val foo = mock[FooWithVarArg]

foo.bar("cow", "blue")
foo.bar("cow", "blue") was called // true

foo.bar("cow")
foo.bar("cow") was called // true

So does mocking with a second parameter list:

trait FooWithSecondParameterList {
  def bar(bell: String)(cheese: Cheese) 
}

val foo = mock[FooWithSecondParameterList]
val cheese = new Gouda

foo.bar("cow")(cheese)

foo.bar("cow")(cheese) was called // true
foo.bar("cow")(*) was called // true

But I can't seem to combine varargs with a second parameter list:

trait FooWithBoth {
  def bar(bells: String*)(cheese: Cheese)
}

val foo = mock[FooWithBoth]
val cheese = new Gouda

foo.bar("cow")(cheese)
foo.bar("cow")(cheese) was called // true
foo.bar("cow")(*) was called // false

Instead, I get a match failure:

Argument(s) are different! Wanted:
foo.bar(
    eqTo(cow),
    <any>
);
-> at ...
Actual invocation has different arguments:
foo.bar(
    WrappedArray(cow),
    Cheese
);

Is there some way to match varargs in the first parameter list while ignoring the second parameter list?

@ultrasecreth
Copy link
Member

@githorse thanks for reporting this, the issue is that the eqTo() matcher is not playing well with varargs, is not a quick fix as many things have to be considered, but in the meantime, you can overcome it by not mixing matchers with raw values (the raw values will be wrapped by an eqTo by the macro).
If you need to match them, you can use argThat or argMatching for the time being to create a matcher that does what you want.

I'll publish a proper fix soon

@githorse
Copy link
Author

githorse commented Jan 4, 2019

@bbonanno - Thanks for your prompt response! In my use case it's difficult to dispense with matching the raw values in the first parameter, so I'm hoping for a workaround here. I tried the argThat and argMatching but could not make that work:

def matches(expected: String) = new ArgumentMatcher[String] {
  override def matches(actual: String): Boolean = actual == expected
}

foo.bar(argThat(matches("cow")))(*)          was called // false
foo.bar(argMatching { case "cow" => true })) was called // false

Am I using these correctly?

I'm still seeing match failures:

Argument(s) are different! Wanted:
fooWithBoth.bar(
    argMatching(...),
    <any>
);
-> at ... 
Actual invocation has different arguments:
fooWithBoth.bar(
    WrappedArray(cow),
    Gouda@6546371
);
-> a

@githorse githorse closed this as completed Jan 4, 2019
@githorse
Copy link
Author

githorse commented Jan 4, 2019

Sorry, closed in error.

@githorse githorse reopened this Jan 4, 2019
@ultrasecreth
Copy link
Member

It's a vararg, so what you want is to match for WrappedArray(cow)

The PR is almost ready anyway, so if it's not urgent you should have the working version later today

@githorse
Copy link
Author

githorse commented Jan 4, 2019

Ah, cool. Thanks. Yeah, I guess for the price you're charging I can probably wait a couple more hours :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants