Skip to content
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

Unable to use value classes for answers in idiomatic API #168

Closed
mikolak-net opened this issue Oct 28, 2019 · 5 comments · Fixed by #170
Closed

Unable to use value classes for answers in idiomatic API #168

mikolak-net opened this issue Oct 28, 2019 · 5 comments · Fixed by #170

Comments

@mikolak-net
Copy link

mikolak-net commented Oct 28, 2019

When running the following code on 1.6.2:

package com.example.test

import org.mockito.{ ArgumentMatchersSugar, IdiomaticMockito }
import org.scalatest.{ FlatSpec, Matchers }

class AnyValMockReproSpec extends FlatSpec with Matchers with IdiomaticMockito with ArgumentMatchersSugar {
  val WString = "foo"

  it should "return a prefixed value for `any` mock" in {
      val decoder = mock[Decoder]
      decoder.decode(any[ValueClass]) answers ((v: ValueClass) => v.value)

      val tested = new Prefixer(decoder)

      tested.prefix(ValueClass(WString)) should be(s"prefix-$WString")
    }

  it should "return a prefixed value for `*` mock" in {
      val decoder = mock[Decoder]
      decoder.decode(*) answers ((v: ValueClass) => v.value)

      val tested = new Prefixer(decoder)

      tested.prefix(ValueClass(WString)) should be(s"prefix-$WString")
    }
}

case class ValueClass(value: String) extends AnyVal

trait Decoder {
  def decode(v: ValueClass): String
}

class Prefixer(decoder: Decoder) {
  def prefix(v: ValueClass): String = s"prefix-${decoder.decode(v)}"
}

the result is the following:

AnyValMockReproSpec:
- should return a prefixed value for `any` mock *** FAILED ***
  java.lang.ClassCastException: java.lang.String cannot be cast to com.example.test.ValueClass
  at com.example.test.AnyValMockReproSpec.$anonfun$new$2$adapted(AnyValMockReproSpec.scala:11)
  at org.mockito.package$.$anonfun$functionToAnswer$1(mockito.scala:30)
  at scala.Function1.$anonfun$andThen$1(Function1.scala:57)
  at org.mockito.stubbing.ScalaAnswer$$anon$2.answer(ScalaAnswer.scala:13)
  at org.mockito.internal.stubbing.StubbedInvocationMatcher.answer(StubbedInvocationMatcher.java:39)
  at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:96)
  at org.mockito.internal.handler.ScalaMockHandler.handle(ScalaMockHandler.scala:37)
  at org.mockito.internal.handler.ScalaNullResultGuardian.handle(ScalaNullResultGuardian.scala:11)
  at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:35)
  at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:61)
  ...
- should return a prefixed value for `*` mock *** FAILED ***
  java.lang.NullPointerException:
  at com.example.test.AnyValMockReproSpec.$anonfun$new$3(AnyValMockReproSpec.scala:20)
  at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
  at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
  at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
  at org.scalatest.Transformer.apply(Transformer.scala:22)
  at org.scalatest.Transformer.apply(Transformer.scala:20)
  at org.scalatest.FlatSpecLike$$anon$5.apply(FlatSpecLike.scala:1682)
  at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
  at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
  at org.scalatest.FlatSpec.withFixture(FlatSpec.scala:1685)

It appears the function serving as the mocked method receives an unwrapped value that is then cast into a value class.

The second case might actually be unrelated to this problem (and may be another issue), included nevertheless for completeness' sake.

@ultrasecreth
Copy link
Member

That's an interesting one (the first one), I have an idea on what the problem is but will probably take a couple of days to be fixed.
For the second one check https://github.com/mockito/mockito-scala#value-class-matchers

@mikolak-net
Copy link
Author

@bbonanno : thanks for the answer! Regarding the second point - ah, completely missed that, sorry. Shall I remove this case from the report, for clarity?

@ultrasecreth
Copy link
Member

@mikolak-net That's all right, otherwise I'd also have to change my comment :)
I'll try to fix this value class issue as soon as I can, thanks for reporting it!

@ultrasecreth
Copy link
Member

Version 1.7.0 should solve it!

@mikolak-net
Copy link
Author

That was fast, thanks!

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

Successfully merging a pull request may close this issue.

2 participants