#StackBounty: #mockito #junit5 #powermockito #byte-buddy mock-maker-inline – Could not initialize inline Byte Buddy mock maker (mockito…

Bounty: 100

I am using Powermockito to mock and spy static classes. Version: 2.0.4

Also using mockito-core version 3.0.0.
In, one of my projects, i am able to mockStatic by enabling mock-maker-inline as specified here
https://github.com/powermock/powermock-examples-maven/blob/master/mockito2/src/test/resources/org/powermock/extensions/configuration.properties

But, when i tried the same approach on my another project, facing the following error:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.ghx.tpm.api.ISubscribedProductParameterService]: Factory method 'subscribedProductParameterService' threw exception; nested exception is java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
Caused by: java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeration@614aeccc
Caused by: java.lang.IllegalStateException: Failed to load MockMaker implementation: mock-maker-inline
Caused by: java.lang.IllegalStateException: Internal problem occurred, please report it. Mockito is unable to load the default implementation of class that is a part of Mockito distribution. Failed to load interface org.mockito.plugins.MockMaker
Caused by: org.mockito.exceptions.base.MockitoInitializationException: 

Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)

Java               : 1.8
JVM vendor name    : Oracle Corporation
JVM vendor version : 25.161-b12
JVM name           : Java HotSpot(TM) 64-Bit Server VM
JVM version        : 1.8.0_161-b12
JVM info           : mixed mode
OS name            : Linux
OS version         : 4.4.0-166-generic

Caused by: java.lang.IllegalStateException: Error during attachment using: net.bytebuddy.agent.ByteBuddyAgent$AttachmentProvider$Compound@3c89bb12
Caused by: java.lang.reflect.InvocationTargetException
Caused by: java.lang.NullPointerException 

Can you please help in resolving this issue?

Additional details:

  • I am mocking static spy class here.
  • byte-buddy jar resolved dependency version is 1.9.10
  • will overlap of mockito2 and powermock-api-mockito2 will cause issue in loading MockMaker? how to resolve them?
  • If the test is executed in IDE it is working fine. but fails when run in maven console.

Additional findings:
Ensured JavassistMockClassLoader is used by adding @PrepareForTest and PowerMockRunner (since one of my other project worked with same configuration)

Facing Null pointer Exception exactly at this line:

ByteBuddyAgent.java (private static void install(AttachmentProvider attachmentProvider, String processId, String argument, AgentProvider agentProvider)
 Attacher.install(attachmentAccessor.getVirtualMachineType(), processId, agentProvider.resolve().getAbsolutePath(), argument);

Classloader while it is failing is – AppLaunchClassLoader. ( Whereas for working project it is URLClassLoader). Not sure if this difference could be a reason.


Get this bounty!!!

#StackBounty: #android #unit-testing #kotlin #mockito Getting a null pointer exception when mocking and spying in a test class

Bounty: 500

Android Studio 3.5.3
Kotlin 1.3

I am trying to test some simple code but I keep getting the following exception:

IllegalStateException: gsonWrapper.fromJson<Map…ring, String>>() {}.type) must not be null

I am using the spy and mocking the return so it will return a null. As I want to test the error path.

Not sure if I am doing something wrong with my stubbing or not. But can’t seem to resolve this exception.

Using a wrapper class to wrap the gson implementation and spying on this in the test

public class GsonWrapper implements IGsonWrapper {

    private Gson gson;

    public GsonWrapper(Gson gson) {
        this.gson = gson;
    }

    @Override public <T> T fromJson(String json, Type typeOf) {
        return gson.fromJson(json, typeOf);
    }
}

Implementation of my class that is under test

class MoviePresenterImp(
        private val gsonWrapper: IGsonWrapper) : MoviePresenter {

    private companion object {
        const val movieKey = "movieKey"
    }

    override fun saveMovieState(movieJson: String) {
            val movieMap = serializeStringToMap(movieJson)

            when (movieMap.getOrElse(movieKey, {""})) {
                /* do something here */
            }
    }

    // Exception return from this method
    private fun serializeStringToMap(ccpaStatus: String): Map<String, String> =
            gsonWrapper.fromJson<Map<String, String>>(ccpaStatus, object : TypeToken<Map<String, String>>() {}.type) // Exception
}

The actual test class, just keeping everything simple

class MoviePresenterImpTest {
    private lateinit var moviePresenterImp: MoviePresenterImp
    private val gsonWrapper: GsonWrapper = GsonWrapper(Gson())
    private val spyGsonWrapper = spy(gsonWrapper)

    @Before
    fun setUp() {
        moviePresenterImp = MoviePresenterImp(spyGsonWrapper)
    }

    @Test
    fun `should not save any movie when there is an error`() {
        // Arrange
        val mapType: Type = object : TypeToken<Map<String, String>>() {}.type
        whenever(spyGsonWrapper.fromJson<Map<String, String>>("{"movie":"movieId"}", mapType)).thenReturn(null)

        // Act
        moviePresenterImp.saveMovieState("{"movie":"movieId"}")

        // Assert here
    }
}

Many thanks for any suggestions,


Get this bounty!!!

#StackBounty: #android #junit #mockito #android-livedata #android-viewmodel jUnit test with LiveData doesn't execute map operator i…

Bounty: 50

Background:

I have a simple application that fetches movie list using rests API call. The project structure is given below,

Activity -> ViewModel -> Repository -> ApiService (Retrofit Interface)
  1. The activity subscribes to a LiveData and listens for events changes

  2. The ViewModel hosts the MediatorLiveData observed by the activity. Initially the ViewModel sets a Resource.loading(..) value in MediatorLiveData.

  3. The ViewModel then calls the repository to get the movie list from ApiService

  4. The ApiService returns a LiveData of either Resource.success(..) or Resource.error(..)

  5. The ViewModel then merges LiveData result from ApiService in MediatorLiveData

My Queries:

  1. Inside the unit test, only the first emit Resource.loading(..) is made by MediatorLiveData from ViewModel. The MediatorLiveData never emits any data from the repository.
  2. Is this the right way to handle loading, success and error events with a single MediatorLiveData?

ViewModel.class

private var discoverMovieLiveData: MediatorLiveData<Resource<DiscoverMovieResponse>> = MediatorLiveData()

fun observeDiscoverMovie(): LiveData<Resource<DiscoverMovieResponse>> {
        return discoverMovieLiveData
    }

fun fetchDiscoverMovies(page: Int) {

        discoverMovieLiveData.value = Resource.loading(null) // this emit get observed immediately 

        val source = movieRepository.fetchDiscoverMovies(page)
        discoverMovieLiveData.addSource(source) {
            discoverMovieLiveData.value = it // never gets called
            discoverMovieLiveData.removeSource(source)
        }
    } 

Repository.class

fun fetchDiscoverMovies(page: Int): LiveData<Resource<DiscoverMovieResponse>> {
        return LiveDataReactiveStreams.fromPublisher(
            apiService.fetchDiscoverMovies(page)
                .subscribeOn(Schedulers.io())
                .map { d ->
                    Resource.success(d) // never gets called in unit test
                }
                .onErrorReturn { e ->
                    Resource.error(ApiErrorHandler.getErrorByThrowable(e), null) // // never gets called in unit test
                }
        )
    }

Unit Test

@Test
fun loadMovieListFromNetwork() {
        val mockResponse = DiscoverMovieResponse(1, emptyList(), 100, 10)
        val call: Flowable<DiscoverMovieResponse> = successCall(mockResponse) // wraps the retrofit result inside a Flowable<DiscoverMovieResponse>
        whenever(apiService.fetchDiscoverMovies(1)).thenReturn(call)

        viewModel.fetchDiscoverMovies(1)

        verify(apiService).fetchDiscoverMovies(1)
        verifyNoMoreInteractions(apiService)

        val liveData = viewModel.observeDiscoverMovie()
        val observer: Observer<Resource<DiscoverMovieResponse>> = mock()
        liveData.observeForever(observer)

        verify(observer).onChanged(
            Resource.loading(null) // never get other events e.g. Resource.success(..)
        )
    }

Resource is a generic wrapper class that wraps data for different scenario e.g. loading, success, error.

class Resource<out T>(val status: Status, val data: T?, val message: String?) {
.......
}

EDIT: #1

I’ve updated my rx thread in repository to run it on main thread. This ends up with a Looper not mocked exception.

fun fetchDiscoverMovies(page: Int): LiveData<Resource<DiscoverMovieResponse>> {
            return LiveDataReactiveStreams.fromPublisher(
                apiService.fetchDiscoverMovies(page)
                    .subscribeOn(AndroidSchedulers.mainThread())
                    .map {...}
                    .onErrorReturn {...}
            )
        }

In test class,

@ExtendWith(InstantExecutorExtension::class)
class MainViewModelTest {

    companion object {
        @ClassRule
        @JvmField
        val schedulers = RxImmediateSchedulerRule()
    }

    @Test
        fun loadMovieListFromNetwork() {
        .....  
       }
}

}

RxImmediateSchedulerRule.class

class RxImmediateSchedulerRule : TestRule {

    private val immediate = object : Scheduler() {
        override fun createWorker(): Worker {
            return ExecutorScheduler.ExecutorWorker(Executor { it.run() })
        }
    }

    override fun apply(base: Statement, description: Description): Statement {
        return object : Statement() {
            @Throws(Throwable::class)
            override fun evaluate() {
                RxJavaPlugins.setInitIoSchedulerHandler { immediate }
                RxJavaPlugins.setInitComputationSchedulerHandler { immediate }
                RxJavaPlugins.setInitNewThreadSchedulerHandler { immediate }
                RxJavaPlugins.setInitSingleSchedulerHandler { immediate }
                RxAndroidPlugins.setInitMainThreadSchedulerHandler { immediate }

                try {
                    base.evaluate()
                } finally {
                    RxJavaPlugins.reset()
                    RxAndroidPlugins.reset()
                }
            }
        }
    }

}

InstantExecutorExtension.class

class InstantExecutorExtension : BeforeEachCallback, AfterEachCallback {

    override fun beforeEach(context: ExtensionContext?) {
        ArchTaskExecutor.getInstance().setDelegate(object : TaskExecutor() {
            override fun executeOnDiskIO(runnable: Runnable) {
                runnable.run()
            }

            override fun postToMainThread(runnable: Runnable) {
                runnable.run()
            }

            override fun isMainThread(): Boolean {
                return true
            }
        })
    }

    override fun afterEach(context: ExtensionContext?) {
        ArchTaskExecutor.getInstance().setDelegate(null)
    }

}


Get this bounty!!!

#StackBounty: #generics #kotlin #mockito Mockito: ClassCastException on generic parent class

Bounty: 50

To abbreviate my unit tests, I created the following parent class:

internal abstract class TestUnitController<CONTROLLER: Any, SERVICE: Any> {

    @Mock
    protected lateinit var service: SERVICE

    @InjectMocks
    protected lateinit var controller: CONTROLLER

    protected abstract fun controllerCall(): CONTROLLER.() -> Unit
    protected abstract fun serviceCall(): SERVICE.() -> Any?

    @Test
    fun `when service returns error should throw ResponseStatusException`() {
        testControllerServiceError(service, serviceCall()) { controllerCall() }
    }

    protected fun <U> testController(value: U, assertions: () -> Unit) {
        testController(service, serviceCall(), value) { assertions() }
    }
}

And a unit test child like the following:

@RunWith(MockitoJUnitRunner::class)
internal class TestUnitCreateCompanyController : TestUnitController<CreateCompanyController, CompanyService>() {

    private val request = CompanyCreateRequest("LOL SARL")

    override fun controllerCall(): CreateCompanyController.() -> Unit = { createCompany(request) }

    override fun serviceCall(): CompanyService.() -> Any? = { createCompany(any()) }

    @Test
    fun `when create company service successful should return created company`() {
        val domain = CompanyDomain(name = request.name)
        testController(domain) {
            controller.createCompany(request).run {
                uuid.shouldEqual(domain.uuid.toString())
                name.shouldEqual(domain.name)
            }
        }
    }
}

However when I run this, I get the following exception:

java.lang.ClassCastException: org.mockito.codegen.Object$MockitoMock$1782227983 cannot be cast to org.m0skit0.fikchador.spring.domain.company.CompanyService

    at org.m0skit0.fikchador.spring.endpoint.company.create.TestUnitCreateCompanyController$serviceCall$1.invoke(TestUnitCreateCompanyController.kt:13)
    at org.m0skit0.fikchador.spring.test.TestUtilsKt.testController(TestUtils.kt:21)
    at org.m0skit0.fikchador.spring.test.TestUnitController.testController(TestUnitController.kt:24)
    at org.m0skit0.fikchador.spring.endpoint.company.create.TestUnitCreateCompanyController.when create company service successful should return created company(TestUnitCreateCompanyController.kt:24)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)


Get this bounty!!!

#StackBounty: #java #mockito #amazon-dynamodb #junit4 #powermockito DynamoDB put Item is not getting mocked using MockiTo & PowerMock

Bounty: 50

Below is the code which I am trying to Mock,

this.dynamoDb.getTable(PropertyUtil.get(Constants.SOME_TABLE_NAME))
        .putItem(
                new PutItemSpec()
                        .withItem(new Item().withString("ID", pId).withString("eId", pEId)
                                .withString("activeInd", pActiveInd)));

What I have tried is below,

mockStatic(AmazonDynamoDBClientBuilder.class);
    when(AmazonDynamoDBClientBuilder.defaultClient()).thenReturn(Mockito.mock(AmazonDynamoDB.class));
    PowerMockito.mockStatic(PropertyUtil.class);
    when(PropertyUtil.get(Constants.Some__ID_MAPPING_TABLE_NAME)).thenReturn("SOME_TABLE_NAME");
    Table vTable = mock(Table.class);
    PutItemSpec vPutItemSpec = mock(PutItemSpec.class);
    PutItemResult vPutItemResult = new PutItemResult();
    PowerMockito.whenNew(PutItemSpec.class).withAnyArguments().thenReturn(vPutItemSpec);
    PowerMockito.when(vTable.putItem(vPutItemSpec)).thenReturn(vPutItemOutcome);

And the error that I get due to this is below,

java.lang.IllegalArgumentException: null
    at com.amazonaws.services.dynamodbv2.document.PutItemOutcome.<init>(PutItemOutcome.java:33) ~[aws-java-sdk-dynamodb-1.11.400.jar:?]
    at com.amazonaws.services.dynamodbv2.document.internal.PutItemImpl.doPutItem(PutItemImpl.java:86) ~[aws-java-sdk-dynamodb-1.11.400.jar:?]
    at com.amazonaws.services.dynamodbv2.document.internal.PutItemImpl.putItem(PutItemImpl.java:63) ~[aws-java-sdk-dynamodb-1.11.400.jar:?]
    at com.amazonaws.services.dynamodbv2.document.Table.putItem(Table.java:168) ~[aws-java-sdk-dynamodb-1.11.400.jar:?]

Please suggest, what I need to fix, I am new to Mock and JUnit.
Thanks in Advance.


Get this bounty!!!