Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock static java methods using Mockk

We are currently working with java with kotlin project, slowly migrating the whole code to the latter.

Is it possible to mock static methods like Uri.parse() using Mockk?

How would the sample code look like?

like image 456
Andrzej Sawoniewicz Avatar asked Apr 10 '18 20:04

Andrzej Sawoniewicz


People also ask

How do you mock a static method in MockK?

Mocking static methodsRather than passing a reference to the class, you pass the class name as a string. You can also choose to pass in a reference to the class, and MockK will figure out the class name. Like object mocks, static mocks behave like spies. The real method will be called if the method is not stubbed.

Can you mock static methods Java?

Since static method belongs to the class, there is no way in Mockito to mock static methods. However, we can use PowerMock along with Mockito framework to mock static methods.

Can MockK be used with Java?

MockK allows mocking static Java methods. The main purpose for it is mocking of Kotlin extension functions, so it is not as powerful as PowerMock, but still does it's job even for Java static methods.

Is MockK better than Mockito?

In Android, there are a lot of frameworks used for mocking in unit testing, such as PowerMock, Mockito, EasyMock, etc. MockK is definitely a better alternative to other mocking frameworks for Kotlin, the official development language for Android. Its main philosophy is first-class support for Kotlin features.


2 Answers

In addition to oleksiyp answer:

After mockk 1.8.1:

Mockk version 1.8.1 deprecated the solution below. After that version you should do:

@Before fun mockAllUriInteractions() {     mockkStatic(Uri::class)     every { Uri.parse("http://test/path") } returns Uri("http", "test", "path") } 

mockkStatic will be cleared everytime it's called, so you don't need to unmock it anymore


DEPRECATED:

If you need that mocked behaviour to always be there, not only in a single test case, you can mock it using @Before and @After:

@Before fun mockAllUriInteractions() {     staticMockk<Uri>().mock()     every { Uri.parse("http://test/path") } returns Uri("http", "test", "path")    //This line can also be in any @Test case }  @After fun unmockAllUriInteractions() {     staticMockk<Uri>().unmock() } 

This way, if you expect more pieces of your class to use the Uri class, you may mock it in a single place, instead of polluting your code with .use everywhere.

like image 102
LeoColman Avatar answered Sep 17 '22 13:09

LeoColman


MockK allows mocking static Java methods. The main purpose for it is mocking of Kotlin extension functions, so it is not as powerful as PowerMock, but still does it's job even for Java static methods.

The syntax would be following:

staticMockk<Uri>().use {     every { Uri.parse("http://test/path") } returns Uri("http", "test", "path")      assertEquals(Uri("http", "test", "path"), Uri.parse("http://test/path"))      verify { Uri.parse("http://test/path") }   } 

More details here: http://mockk.io/#extension-functions

like image 25
oleksiyp Avatar answered Sep 18 '22 13:09

oleksiyp