Running from Ant, not IntelliJ, throws "Mockito cannot mock this class:" error for spy

529 views
Skip to first unread message

Dave Sims

unread,
Oct 9, 2011, 1:34:31 AM10/9/11
to mockito
When using the IntelliJ runner I can use spy just fine, but when
running from ant it throws the following error:

Mockito cannot mock this class: class
com.livingsocial.android.api.ResultProcessorTest$1

The line that throws the error is in a @Before setup method:

spiedProcessor = spy(resultProcessor);

It only happens on "spy".

Any ideas?

Thanks,
Dave

Dave Sims

unread,
Oct 9, 2011, 9:27:50 PM10/9/11
to mockito
I figured part of it out -- for some reason running from IntelliJ, Mockito allows spying on anonymous classes, but running from ant doesn't. Both are using the same versions of Mockito and JUnit.

The work-around for now is to declare a public inner class and use that to instantiate the class to be spied on, rather than an anonymous inner class.


--
You received this message because you are subscribed to the Google Groups "mockito" group.
To post to this group, send email to moc...@googlegroups.com.
To unsubscribe from this group, send email to mockito+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mockito?hl=en.


Brice Dutheil

unread,
Oct 10, 2011, 3:59:44 AM10/10/11
to moc...@googlegroups.com
Hi Dave,

Nice you got it worked out.

However could you provide some details about your ant configuration, maybe the used JDK, which mockito package, any other details that you deem interesting.

Thx in advance.


-- 
Brice

Dave Sims

unread,
Oct 10, 2011, 9:46:36 AM10/10/11
to moc...@googlegroups.com
Sure Bruce.

I tried changing mockito and JUnit versions on both sides from JUnit 4.8 up to to 4.10, and Mockito 1.8.5 and 1.9.0-rc1. None of those changes made a difference, and as far as I can tell, both IntelliJ and Ant were aligned for every attempt.

The current configuration is what I started with: JUnit 4.8 and Mockito 1.8.5. Ant version was always 1.8.2.

The ant test target is pretty boilerplate:

<target name="test" depends="compile,compile.tests" description="test all">
        <mkdir dir="${test.dir}/reports/"/>
        <junit printsummary="true" showoutput="true" failureproperty="junit.failure">
            <formatter type="brief" usefile="false"/>
            <formatter type="plain"/>
            <formatter type="xml"/>
            <batchtest todir="${test.dir}/reports/">
                <fileset dir="${test.dir}">
                    <include name="**/*Test.java"/>
                </fileset>
            </batchtest>
            <classpath>
                <pathelement path="${out.dir}/classes"/>
                <pathelement path="${out.test.dir}"/>
                <fileset dir="${test.libs.dir}" includes="*.jar"/>
                <fileset dir="${external.libs.dir}" includes="*.jar"/>

                <path refid="android.target.classpath"/>

            </classpath>
        </junit>
        <fail if="junit.failure" message="Unit test(s) failed. See reports!"/>
    </target>

The test in question was failing on something a lot like this in a @Before method:

  resultProcessor = new ApiResultProcessor(){
    @Override
            public void handleSuccess(Object resultObject) {
            }
        };
    };
    spiedProcessor = spy(resultProcessor);


It failed on the line that attempted to spy on resultProcessor, with the error:

"Mockito cannot mock this class: class com.livingsocial.android.api.ResultProcessorTest$1. Mockito can only mock visible & non-final classes."

I overlooked the "$1" -- that's the anonymous class. The work-around was to create an inner class, which *has* to be declared public rather than default visibility:

    public class TestResultProcessor extends ApiResultProcessor {
        @Override
        public void handleSuccess(Object resultObject) {
        }
    }

Then the setup method can use:

   resultProcessor = new TestResultProcessor();
   spiedProcessor = spy(resultProcessor);

Hope that helps.

Dave

Dave Sims

unread,
Oct 10, 2011, 9:50:12 AM10/10/11
to moc...@googlegroups.com
Oh, and the Mockito package was "all".

Brice Dutheil

unread,
Oct 10, 2011, 12:19:45 PM10/10/11
to moc...@googlegroups.com
Hi,

I couldn't reproduce the issue (as I expected, since IntelliJ runs the tests with the configured JDK). However I suppose the problem might reside in the Android stuff, especially in your ant config. I don't know much about Android development. But that might be the explanation. I don't have the Android setup, but if you could package a very simple project illustrating the issue, I will take a further look.


For information I tried on JDK 5 / JDK 6. Dependencies were limited to the JDK, Junit 4.8, Mockito 1.8.5. And the code looks like this :

public interface Yup {
    void salute();
}

public class YupTest {
    @Test
    public void dont_fail() throws Exception {
        Yup tested = new Yup() {
            public void salute() {
                // noop
            }
        };

        spy(tested);
    }
}


-- 
Brice

Dave Sims

unread,
Oct 10, 2011, 12:27:03 PM10/10/11
to moc...@googlegroups.com
Ha, yeah did I not mention I was on Android?   : )

Sure, busy day today (and week) but when I get a chance I'll reproduce in a small Android project and get it to you.

Thanks Bruce,
Dave

Brice Dutheil

unread,
Oct 10, 2011, 12:29:04 PM10/10/11
to moc...@googlegroups.com
Typo error, it's Brice, not Bruce ;)



-- 
Brice

Dave Sims

unread,
Oct 10, 2011, 12:33:54 PM10/10/11
to moc...@googlegroups.com
Pfft. Sorry Bruc -- Brice!.  

Brice Dutheil

unread,
Oct 10, 2011, 12:45:15 PM10/10/11
to moc...@googlegroups.com
No problemo! :)


-- 
Brice
Reply all
Reply to author
Forward
0 new messages