6

I have the following code:

@RunWith(MockitoJUnitRunner::class)
class OnboardingViewModelTest {

    @Mock lateinit var authService : AuthService
    lateinit var internetProvider: InternetStatusProvider
    private lateinit var viewModel: OnboardingViewModel

    @Before
    fun setup() {
        internetProvider = mock()
        whenever(internetProvider.hasInternet()).thenReturn(true)
    }

The constructor of InternetStatusProvider looks like so:

InternetStatusProvider(context:Context)

I am getting a NullPointerException when stubbing the internetProvider.hasInternet() method because that method's implementation uses the context passed in the constructor and the real method is being called?

What am I missing here? the whole point is to stub the real implementation of this method?

StuStirling
  • 15,601
  • 23
  • 93
  • 150
  • 2
    What is the signature of the `hasInternet()` function? If it is not `open`, then the call `internetProvider.hasInternert()` will be executed, since Mockito cannot stub a final method. – nhaarman Jul 12 '17 at 11:19
  • Genius, should have been pretty obvious I guess. So stubbed methods need to be open... Not sure I like this. Please submit this as an answer and I'll accept. – StuStirling Jul 12 '17 at 11:27

1 Answers1

21

Mockito cannot stub final methods. If you try to execute a final method from a mocked instance, the real code will be executed. Since Kotlin's functions are final by default, you'd have to add the open modifier to the function.

There is also an incubating feature in Mockito that does allow mocking of final classes and methods, which may be worth a look.

nhaarman
  • 98,571
  • 55
  • 246
  • 278
  • [Here's](https://stackoverflow.com/a/43310572/4465208) an easy way to start using the inline version of Mockito. – zsmb13 Jul 12 '17 at 13:13