Problems with Mockito

I have an error when I run the test as below:

org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class com.bignerdranch.android.beatbox.BeatBox.

Mockito can only mock non-private & non-final classes.
If you’re not sure why you’re getting this error, please report to the mailing list.

Java : 1.8
JVM vendor name : JetBrains s.r.o
JVM vendor version : 25.112-b06
JVM name : OpenJDK 64-Bit Server VM
JVM version : 1.8.0_112-release-b06
JVM info : mixed mode
OS name : Windows 10
OS version : 10.0

Underlying exception : java.lang.IllegalArgumentException: Could not create type

at com.bignerdranch.android.beatbox.SoundViewModelTest.setUp(SoundViewModelTest.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
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.RunBefores.evaluate(RunBefores.java:24)
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.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
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.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Caused by: java.lang.IllegalArgumentException: Could not create type
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:140)
at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:346)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:161)
at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:355)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:32)
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMockType(SubclassByteBuddyMockMaker.java:71)
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:42)
at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:25)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:65)
at org.mockito.Mockito.mock(Mockito.java:1821)
at org.mockito.Mockito.mock(Mockito.java:1734)
… 36 more
Caused by: java.lang.NoClassDefFoundError: android/content/Context
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
at java.lang.Class.getDeclaredConstructors(Class.java:2020)
at net.bytebuddy.description.method.MethodList$ForLoadedMethods.(MethodList.java:90)
at net.bytebuddy.description.type.TypeDescription$ForLoadedType.getDeclaredMethods(TypeDescription.java:7232)
at net.bytebuddy.description.type.TypeDescription$Generic$OfNonGenericType.getDeclaredMethods(TypeDescription.java:3349)
at net.bytebuddy.description.type.TypeDescription$Generic$LazyProjection.getDeclaredMethods(TypeDescription.java:5242)
at net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy$Default$5.doExtractConstructors(ConstructorStrategy.java:157)
at net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy$Default.extractConstructors(ConstructorStrategy.java:176)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.applyConstructorStrategy(SubclassDynamicTypeBuilder.java:185)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:162)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:155)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:2639)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:2741)
at org.mockito.internal.creation.bytebuddy.SubclassBytecodeGenerator.mockClass(SubclassBytecodeGenerator.java:114)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:37)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:34)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:138)
… 47 more
Caused by: java.lang.ClassNotFoundException: android.content.Context
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
… 65 more

Process finished with exit code -1

, and classes:

SoundViewModelTest.java
package com.bignerdranch.android.beatbox;

import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;

/**
 * Created by behin on 10/15/2017.
 */
public class SoundViewModelTest {
	private BeatBox mBeatBox;
	private Sound mSound;
	private SoundViewModel mSubject;

	@Before
	public void setUp() throws Exception {
		mBeatBox = mock(BeatBox.class);
		mSound = new Sound("assetPath");
		mSubject = new SoundViewModel(mBeatBox);
		mSubject.setSound(mSound);
	}

	@Test
	public void exposesSoundNameAsTitle() {
		assertThat(mSubject.getTitle(), is(mSound.getName()));
	}
}
BeatBox.java
package com.bignerdranch.android.beatbox;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioManager;
import android.media.SoundPool;
import android.util.Log;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by behin on 10/11/2017.
 */

public class BeatBox {
	private static final String TAG = "BeatBox";
	private static final String SOUNDS_FOLDER = "sample_sounds";
	private static final int MAX_SOUNDS = 5;

	private AssetManager mAssets;
	private List<Sound> mSounds = new ArrayList<>();
	private SoundPool mSoundPool;

	public BeatBox(Context context) {
		mAssets = context.getAssets();
		// This old constructor is deprecated but needed for compatibility
		mSoundPool = new SoundPool(MAX_SOUNDS, AudioManager.STREAM_MUSIC, 0);
		loadSounds();
	}

	public void play(Sound sound) {
		Integer soundId = sound.getSoundId();

		if(soundId == null) {
			return;
		}

		mSoundPool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f);
	}

	private void loadSounds() {
		String[] soundNames = new String[0];

		try {
			soundNames = mAssets.list(SOUNDS_FOLDER);
			Log.i(TAG, "Found " + soundNames.length + " sounds");
		} catch (IOException e) {
			Log.e(TAG, "Could not list assets", e);
		}

		for (String filename : soundNames) {
			try {
				String assetPath = SOUNDS_FOLDER + "/" + filename;
				Sound sound = new Sound(assetPath);
				load(sound);
				mSounds.add(sound);
			} catch (IOException ieo) {
				Log.e(TAG, "Could not load sound " + filename, ieo);
			}

		}
	}

	private void load(Sound sound) throws IOException {
		AssetFileDescriptor afd = mAssets.openFd(sound.getAssetPath());
		int soundId = mSoundPool.load(afd, 1);
		sound.setSoundId(soundId);
	}

	public List<Sound> getSounds() {
		return mSounds;
	}
}

I tried several solutions from the webs then I rewrite the app and check all codes but the problem is not solved :tired_face:.
please help! :smiley:

Thanks!

Edit:
I forget to include build.gradle:

BeatBox\app\build.gradle
apply plugin: 'com.android.application'

android {
	compileSdkVersion 26
	buildToolsVersion "26.0.0"
	defaultConfig {
		applicationId "com.bignerdranch.android.beatbox"
		minSdkVersion 19
		targetSdkVersion 26
		versionCode 1
		versionName "1.0"
		testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
	}
	buildTypes {
		release {
			minifyEnabled false
			proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
		}
	}
	dataBinding {
		enabled = true
	}
}

dependencies {
	compile fileTree(include: ['*.jar'], dir: 'libs')
	androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
		exclude group: 'com.android.support', module: 'support-annotations'
	})
	compile 'com.android.support:appcompat-v7:26.+'
	compile 'com.android.support.constraint:constraint-layout:1.0.2'
	testCompile 'junit:junit:4.12'
	compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
	testCompile 'org.mockito:mockito-core:2.11.0'
	testCompile 'org.hamcrest:hamcrest-junit:2.0.0.0'
}

I had the same issue. I changed my target and compile SDK versions from API 26 to API 25, and the build tools version from 26.0.0 to 25.0.2. I also changed the appcompat and recyclerview libraries from 26 to 25.3.1. After that it worked like normal. I’ll try and attach my build.gradle file for reference


BeatBox\app\build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion '25.0.2'
    defaultConfig {
        applicationId "com.bignerdranch.android.beatbox"
        minSdkVersion 19
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    dataBinding {
        enabled = true;
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:recyclerview-v7:25.3.1'
    testCompile 'org.mockito:mockito-core:2.11.0'
    testCompile 'org.hamcrest:hamcrest-junit:2.0.0.0'
}
2 Likes

Thank you for your solution. I tried it and the problem is solved.

After that , an idea came to me to try using old version of mock and keep other Gradle Configurations and project files same. So, instead of using testCompile 'org.mockito:mockito-core:2.11.0' I use testCompile 'org.mockito:mockito-core:2.2.1' and it’s work, too. But I don’t know if it is good idea.

I use org.mockito:mockito-core:2.13.0 with buildToolsVersion “26.0.3”. It works well.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.3"
    defaultConfig {
        applicationId "com.star.beatbox"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    dataBinding {
        enabled = true
    }
    compileOptions {
        targetCompatibility 1.8
        sourceCompatibility 1.8
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:support-v4:26.1.0'
    implementation 'com.android.support:recyclerview-v7:26.1.0'
    testImplementation 'org.mockito:mockito-core:2.13.0'
    testImplementation 'org.hamcrest:hamcrest-junit:2.0.0.0'
}

Hi @BC2017/@blkxltng/@crystalDf/@cstewart,

The correct import static statements to have in the SoundViewModelTest.java file are:

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.mock;

After doing that if you try to rerun the tests it may fail with this error:
java.lang.NoClassDefFoundError: android/content/Context

To fix that I deleted the .gradle folder, rebuilt the app and reran the tests without issue. Alternatively you can run ./gradlew clean test in the terminal