5

Is it possible to mock the Android Camera class ?

@Override
public void setUp() {
    _camera = Mockito.mock(Camera.class);
}

fails to generate a mock (ExceptionInitializerError in Mockito's createProxyClass).

Should I create some kind of wrapper around the Camera (not my favorite solution, would really like to just mock the class...)?

Or, should I use a different mock library then Mockito?

Hope somebody can point me in the right direction.

Complete stacktrace of ExceptionInitializerError

java.lang.ExceptionInInitializerError
at org.mockito.internal.creation.jmock.ClassImposterizer.createProxyClass(ClassImposterizer.java:85)
at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:62)
at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56)
at org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java:23)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
at org.mockito.Mockito.mock(Mockito.java:1243)
at org.mockito.Mockito.mock(Mockito.java:1120)
at com.cleancode.lifesaver.flashlight.test.FlashLightTests.setUp(FlashLightTests.java:20)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:190)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:175)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1661)
Caused by: java.lang.VerifyError: org/mockito/cglib/core/ReflectUtils
at org.mockito.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:167)
at org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217)
at org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:109)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:105)
at org.mockito.cglib.proxy.Enhancer.<clinit>(Enhancer.java:70)
... 18 more
Mohammad Ersan
  • 12,304
  • 8
  • 54
  • 77
bas
  • 13,550
  • 20
  • 69
  • 146

3 Answers3

6

The answer is late but here is a mock camera example for Android.

You can set the VideoFileInputSource to mock camera from video file

textureVideoInputSource = new VideoFileInputSource(this, "mock_input_video.mp4");

or you can enable hardware camera for video stream.

textureVideoInputSource = new CameraTextureVideoInputSource(this);

You can find the complete sample project here. https://github.com/muneikh/MockCamera

muneikh
  • 2,067
  • 5
  • 25
  • 59
  • Thx for the answer anyway. I stopped my android activities a while ago, so I won't be able to validate your answer. If "the community" states this actually works I will mark it as accepted nonetheless. – bas Jul 19 '16 at 10:47
  • 1
    @bas maybe now, you can consider this as a community accepted answer? 100% more acceptance than the currently accepted answer ;) – muneikh Dec 04 '18 at 17:28
3

In your stacktrace, notice the substring ".CglibMockMaker": that's the problem here. CGLib doesn't work on android -- there's a plugin for Mockito specifically for android that uses dexmaker, which is like CGLib but works for dalvik. Just search for dexmaker mockito and you should be on the right path.

You still won't be able to mock Camera.open() (the static factory method), but you can refactor your code around that. What matters is that Camera is not a final class; the rest is just awkward plumbing for the test, which you should just accept as the tax for writing well-tested android apps.

  • [The mockito offical doc](http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html) states that "Mockito doesn't mock final methods". Most Camera's methods are final. So it seems mocking Camera is not an option. – lacton Jan 28 '14 at 21:51
1

I think the ExceptionInInitializerError exception is happening because Camera is only supposed to be instantiated through its static open() method, so some kind of static initialization is failing when Mockito tries to create a mock. It doesn't seem to be possible to work around that. Perhaps it expects to interact with hardware that isn't present in a test environment? You may be able to use PowerMock to mock it anyway, or you may just want to go with your stated alternative of a wrapper class with an interface.

Chris Mantle
  • 6,595
  • 3
  • 34
  • 48
  • Been trying to get a successful test whole day now, no luck yet. I wrapped the Camera now, but still Android JUnit refuses to execute a trivial test with mockito. Read about 100 pages on the web, and got nowhere... Unbelievable. Will give PowerMock a shot. – bas Sep 02 '13 at 14:00
  • Bad times. Any luck with PowerMock? – Chris Mantle Sep 05 '13 at 09:43
  • I gave up on it :). Wrapped the camera so that it doesn't annoy me too much. I will try powermock soon though. +1 for the pointers and help – bas Sep 15 '13 at 14:58
  • finally took the time to test this with PowerMock, but no luck there either. The test fails on a javaassist/NotFoundException. Not sure if this is related to the android camera (wouldn't make a lot of sense, since it's just a java class in the end...). Anyway, I will stick with the wrapper for now and carry on :). Thanks for the help. – bas Sep 20 '13 at 14:51