java - Powermock error mock object injected using spring when mocking static object -


i using powermock easy mock mock static method of class. have 2 test cases written, if run independently run fine, give me error while running simultaneously.

cartest:

@runwith(powermockrunner.class) @preparefortest({ servicecaller.class }) public class cartest {    servicecaller           mockservicecallerobjecttoreturn;    public cartest() {     powermock.mockstaticpartial(servicecaller.class, "getinstance");     mockservicecallerobjecttoreturn = powermock.createmock(servicecaller.class);     easymock.expect(servicecaller.getinstance()).andreturn(mockservicecallerobjecttoreturn);   }    @test   public void test1() throws ioexception {     powermock.reset(mockservicecallerobjecttoreturn);     powermock.reset(servicecaller.class);      easymock.expect(servicecaller.getinstance()).andreturn(mockservicecallerobjecttoreturn);      easymock.expect(mockservicecallerobjecttoreturn.checkvalidity("testdriver")).andreturn(false);      powermock.replay(mockservicecallerobjecttoreturn);     powermock.replay(servicecaller.class);      car car = carfactory.getinstance().getcar();     boolean candrive = car.drive("testdriver");     assert.assertequals(candrive, false);      powermock.verify(mockservicecallerobjecttoreturn);     powermock.verify(servicecaller.class);   }    @test   public void test2() throws ioexception {     powermock.reset(mockservicecallerobjecttoreturn);     powermock.reset(servicecaller.class);      easymock.expect(servicecaller.getinstance()).andreturn(mockservicecallerobjecttoreturn);      easymock.expect(mockservicecallerobjecttoreturn.checkvalidity("testdriver")).andreturn(false);      powermock.replay(mockservicecallerobjecttoreturn);     powermock.replay(servicecaller.class);      car car = carfactory.getinstance().getcar();     boolean candrive = car.drive("testdriver");     assert.assertequals(candrive, false);      powermock.verify(mockservicecallerobjecttoreturn);     powermock.verify(servicecaller.class);   } } 

carfactory:

public class carfactory {       private static final string               car_spring_context_xml = "/com/archit/mock/spring-config/carspringcontext.xml";       protected static final applicationcontext context                = new classpathxmlapplicationcontext(new string[] { car_spring_context_xml });       private static final carfactory           instance               = new carfactory();       public static carfactory getinstance() {     return instance;   }       public car getcar() {     return context.getbean("car", car.class);   }     } 

car:

package com.archit.mock; public class car {   private final servicecaller        servicecaller;   public car(final servicecallerfactory servicecallerfactory) {     this.servicecaller = servicecallerfactory.getservicecaller();   }   public boolean drive(final string driver) {     return (servicecaller.checkvalidity(driver));   } } 

servicecaller:

package com.archit.mock; public class servicecaller {   private static class servicecallerholder {     private static servicecaller instance = new servicecaller();   }   public static servicecaller getinstance() {     return servicecallerholder.instance;   }   public boolean checkvalidity(final string x) {     // call     throw new illegalstateexception("this should have been mocked");   } } 

servicecallerfactory:

package com.archit.mock; public class servicecallerfactory {   public servicecaller getservicecaller() {     return servicecaller.getinstance();   } } 

spring config:

<bean name="car" class="com.archit.mock.car">     <constructor-arg>         <ref bean="servicecallerfactory" />     </constructor-arg> </bean>  <bean name="servicecallerfactory" class="com.archit.mock.servicecallerfactory" /> 

error:

java.lang.assertionerror:    unexpected method call servicecaller.checkvalidity("testdriver"):     servicecaller.checkvalidity("testdriver"): expected: 1, actual: 2   @ org.easymock.internal.mockinvocationhandler.invoke(mockinvocationhandler.java:44)   @ org.easymock.internal.objectmethodsfilter.invoke(objectmethodsfilter.java:85)   @ org.easymock.internal.classproxyfactory$mockmethodinterceptor.intercept(classproxyfactory.java:94)   @ com.archit.mock.servicecaller$$enhancerbycglib$$9848ad9e.checkvalidity(<generated>)   @ com.archit.mock.car.drive(car.java:12)   @ com.archit.mock.cartest.test2(cartest.java:60)   @ sun.reflect.nativemethodaccessorimpl.invoke0(native method)   @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:57)   @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)   @ java.lang.reflect.method.invoke(method.java:601)   @ org.junit.internal.runners.testmethod.invoke(testmethod.java:66)   @ org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateimpl$powermockjunit44methodrunner.runtestmethod(powermockjunit44runnerdelegateimpl.java:312)   @ org.junit.internal.runners.methodroadie$2.run(methodroadie.java:86)   @ org.junit.internal.runners.methodroadie.runbeforesthentestthenafters(methodroadie.java:94)   @ org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateimpl$powermockjunit44methodrunner.executetest(powermockjunit44runnerdelegateimpl.java:296)   @ org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateimpl$powermockjunit44methodrunner.runbeforesthentestthenafters(powermockjunit44runnerdelegateimpl.java:284)   @ org.junit.internal.runners.methodroadie.runtest(methodroadie.java:84)   @ org.junit.internal.runners.methodroadie.run(methodroadie.java:49)   @ org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateimpl.invoketestmethod(powermockjunit44runnerdelegateimpl.java:209)   @ org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateimpl.runmethods(powermockjunit44runnerdelegateimpl.java:148)   @ org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateimpl$1.run(powermockjunit44runnerdelegateimpl.java:122)   @ org.junit.internal.runners.classroadie.rununprotected(classroadie.java:34)   @ org.junit.internal.runners.classroadie.runprotected(classroadie.java:44)   @ org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateimpl.run(powermockjunit44runnerdelegateimpl.java:120)   @ org.powermock.modules.junit4.common.internal.impl.junit4testsuitechunkerimpl.run(junit4testsuitechunkerimpl.java:102)   @ org.powermock.modules.junit4.common.internal.impl.abstractcommonpowermockrunner.run(abstractcommonpowermockrunner.java:53)   @ org.powermock.modules.junit4.powermockrunner.run(powermockrunner.java:42)   @ org.eclipse.jdt.internal.junit4.runner.junit4testreference.run(junit4testreference.java:50)   @ org.eclipse.jdt.internal.junit.runner.testexecution.run(testexecution.java:38)   @ org.eclipse.jdt.internal.junit.runner.remotetestrunner.runtests(remotetestrunner.java:467)   @ org.eclipse.jdt.internal.junit.runner.remotetestrunner.runtests(remotetestrunner.java:683)   @ org.eclipse.jdt.internal.junit.runner.remotetestrunner.run(remotetestrunner.java:390)   @ org.eclipse.jdt.internal.junit.runner.remotetestrunner.main(remotetestrunner.java:197) 

other observations:

  • making object scope prototype in spring config works fine.
  • both tests when run individually work fine.
  • based on above 2, seems problem re-setting mocks.

i've found easier mocks have them start new objects each time tests run. can achieve having mock objects @ top private variables, using mockito.mock annotation:

@mock private mockoneclass mockone; ... @mock private mocknclass mockn; 

then using junit before annotation, create setup function of sort initializes mock objects:

@before public void setup() {     // initialize @mock objects     mockitoannotations.initmocks(this); } 

this way, before each test runs new mock created, can apply amount of expects , functionality to, without having worry clearing out old mocking done in previous test. if have mock know provide specific functionality (static singleton mock getinstance calls example) can called in setup function keep tests cleaner of mock resetting.

i have test has 10+ tests run in row uses framework. not make lot easier read, makes setting tests scratch fast. being able copy old mock setups in tests , remove/change pieces easier having upkeep every mock object every test, doesn't extend once start getting more tests.


Comments

Popular posts from this blog

ios - UICollectionView Self Sizing Cells with Auto Layout -

node.js - ldapjs - write after end error -

DOM Manipulation in Wordpress (and elsewhere) using php -