mockito-kotlin icon indicating copy to clipboard operation
mockito-kotlin copied to clipboard

Mocking an interface with non-nullable properties sets the properties as null

Open jordigarcl opened this issue 5 years ago • 3 comments
trafficstars

It looks like Mockito is using null as a default value for properties in a interface even though they are non-nullable.

Reproduce:

interface Dog {
  val name: String
}

class DogCaller {
  fun callDog(dog: Dog) = callSomeone(dog.name)
  private fun callSomeone(name: String) = "Hey $name come here!"
}


class DogCallerTests {

  private val dogCaller = DogCaller()

  @Test
  fun `dog caller should call dog by its name`() {
    val beagle: Dog = mock()

    // This makes the test pass 
    // whenever(beagle.name).thenReturn("Firulais")
    
    dogCaller.callDog(beagle)

    verify(beagle).name // This fails cause it detects dog.name : String = null !
  }
}

jordigarcl avatar Jan 15 '20 15:01 jordigarcl

Your reproducer passes when I try it out. Maybe try checking your imports.

Also returning null is the expected behaviour when a method hasn't been stubbed (depending on the type) - more info here.

bohsen avatar Jan 15 '20 21:01 bohsen

Sorry, now I see I got this error cause inside callDog() I passed dog.name to another function which expected a non-nullable type. That's where the nullability of String check failed.

Though from thecastNull() in the file you referenced I see this is a totally intentional behaviour. Should it be the case though? String has always been a "special" type. I expected the mock to return a '"nice" value such as "".

jordigarcl avatar Jan 15 '20 21:01 jordigarcl

It would make sense to handle it that way. Would actually solve the issue seen in #241 without using the proposed workaround I believe. Strings have always been kind of problematic in regards to Mockito-kotlin.

bohsen avatar Jan 15 '20 22:01 bohsen