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

Why mockito cannot mock fun interface? #442

Closed
Jacks0N23 opened this issue Sep 13, 2021 · 1 comment
Closed

Why mockito cannot mock fun interface? #442

Jacks0N23 opened this issue Sep 13, 2021 · 1 comment

Comments

@Jacks0N23
Copy link

Jacks0N23 commented Sep 13, 2021

For ex. my code looks like this:

fun interface FunInterfaceToTest : (String) -> Int

val myInterfaceToTest: FunInterfaceToTest = spy(
    FunInterfaceToTest { mock() }
)

If new IR kotlin compiler backend is enabled then

launching test with SAM throws this:

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class my.company.package.test$sam$my_company_package_FunInterfaceToTest$0.
Can not mock final classes with the following settings :
 - explicit serialization (e.g. withSettings().serializable())
 - extra interfaces (e.g. withSettings().extraInterfaces(...))

You are seeing this disclaimer because Mockito is configured to create inlined mocks.
You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc.

OR
if use anonymous object than i got this:

org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class java.lang.Integer
Mockito cannot mock/spy because :
 - Cannot mock wrapper types, String.class or Class.class

in some cases I got this:

Argument passed to verify() is of type  and is not a mock!
Make sure you place the parenthesis correctly!
See the examples of correct verifications:
    verify(mock).someMethod();
    verify(mock, times(10)).someMethod();
    verify(mock, atLeastOnce()).someMethod();
org.mockito.exceptions.misusing.NotAMockException: 

BUT
If in build.gradle file I enable old kotlin compiler backend than

android {
    kotlinOptions {
        useOldBackend = true
    }
}

everything works fine, but why??

Full Test Suite
class Test : BehaviorSpec({

  Given("test given") {
      val myInterfaceToTest: FunInterfaceToTest = spy(
          object : FunInterfaceToTest {
              override fun invoke(it: String): Int {
                  return mock()
              }
          }
      )
      When("test when") {
          myInterfaceToTest("")
          Then("so") {
              verify(myInterfaceToTest, never()).invoke(any())
          }
      }
  }
})

fun interface FunInterfaceToTest : (String) -> Int
@abelkov
Copy link

abelkov commented Sep 20, 2021

See explanation in #441

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