Powermockito and overriding hashcode

214 views
Skip to first unread message

Horace Le Cheval

unread,
Oct 14, 2014, 8:41:42 AM10/14/14
to powe...@googlegroups.com
Hi guys,
(maybe?) stupid question :

i'm babystepping with powermock (1.5.6), 
in order to test (mockito (1.9.5) / Junit (4.10) ) some legacy code dealing with hashcode.

I keep bumping on the mock of a class overriding the hashcode method, which raises an exception(*) 
and i did not manage to find an answer on the webs.

(*) exception being
org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
   It is a limitation of the mock engine.

Not sure, but might be related to the post "18 Dec 2013: Cannot mock equals and hashCode in own class, while it works with InitialContext"

Basically here is a reproduction of my issue (SubHashMap is just an example, case occurs with standalone class):

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.util.HashMap;

import static org.junit.Assert.assertTrue;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;

@RunWith(PowerMockRunner.class)

@PrepareForTest({HashCodeTest.SubHashMap.class})

public class HashCodeTest {

@Test
public void  getHashmap() {
HashMap actor = mock(HashMap.class);
when(actor.hashCode()).thenReturn(123456);
assertTrue("yay i'm good", true);
}

@Test
public void  getsubHashmap() {
try {
SubHashMap actor = mock(SubHashMap.class);
when(actor.hashCode()).thenReturn(123456);
} catch (Exception e) {
assertTrue("boo i'm bad",false);
e.printStackTrace();
}
}

public class SubHashMap extends HashMap{
@Override
public int hashCode() {
return super.hashCode();
}

@Override
public boolean equals(Object o) {
return super.equals(o);
}
}

}

Does someone, by any chance, have a suggestion ? 

Thanks and Cheers

Johan Haleby

unread,
Oct 15, 2014, 1:34:50 AM10/15/14
to powe...@googlegroups.com
Looks like a bug to me. A work-around would be to stub it instead:

stub(method(SubHashMap.class, "hashCode")).toReturn(123456);
SubHashMap actor = new SubHashMap();

int hashCode = actor.hashCode();

where "stub" is statically imported from org.powermock.api.support.membermodification.MemberModifier.stub and "method" from org.powermock.api.support.membermodification.MemberMatcher.method.

/Johan

--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To unsubscribe from this group and stop receiving emails from it, send an email to powermock+...@googlegroups.com.
To post to this group, send email to powe...@googlegroups.com.
Visit this group at http://groups.google.com/group/powermock.
For more options, visit https://groups.google.com/d/optout.

Horace Le Cheval

unread,
Oct 15, 2014, 3:51:49 AM10/15/14
to powe...@googlegroups.com
Ok,
thanks a lot for your swift feedback,

Using the real object would trigger its hashcode/equals implementation, hence would not require to stub it.
As you suggest, i will probably rewire my factory to return objects instead of mocks for these cases.

Thanks again and have a nice day.

H
Reply all
Reply to author
Forward
0 new messages