0

I have a method contains String comparison:

if (stringA.equals(stringB)) { ... }

And in the unit test, I tried:

String stringA = PowerMockito.mock(String.class);
String stringB = PowerMockito.mock(String.class);
when(stringA.equals(stringB)).thenReturn(false);

But this would actually return true. Could anyone tell me how to mock String#equals method by PowerMockito? Thanks.

Jing Li
  • 14,547
  • 7
  • 57
  • 69
  • 1
    Why do you think you want to do this? – Joe C Nov 19 '16 at 21:58
  • Possibly useful [discussion on the Mockito group](https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mockito/d25SPtJ4108/Bj1kbarjBAAJ) highlighting that trying to mock Strings may break your JDK because of how they're handled internally. There's not really an exhaustive explanation on that thread, however I can't figure out a reason to try mocking Strings... Perhaps you're looking at your problem from an incorrect angle. Can you share some thoughts on this? – Morfic Nov 21 '16 at 12:22
  • For the record: I doubt that you will ever hear much else on this question, so please consider if one of the answers is helpful enough for accepting. – GhostCat Jun 13 '17 at 19:40

2 Answers2

1

Besides the fact that mocking final methods is hard; especially when you try to manipulate such core classes as java.lang.String; the real point here is of a different nature: it is simply wrong to override String.equals() for a test.

Simply spoken: if your logic relies on comparing two objects, then you should focus on coming up with a design that allows you to inject at least one of those two values - instead of using dirty dirty hacks to manipulate the internals of the corresponding equals method!

But if your design is such that you think you need PowerMockito in order to make it testable (by overriding that String.equals()) methods; most likely: you simply created untestable code in the first place.

Thus my "non-answer". Step back from your current approach, check out these videos to learn how to write testable code; then come back and rework your design.

Far too often people create a broken design; and then they assume that PowerMock(ito) is the way to "fix" the consequences of that broken design. And far too often, the exact reverse is true: if you think you need PowerMock(ito), then your design should be reworked.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
0

Java string is a final class,hence you have to use mocking final strategies,like @PrepareForTest(ClassWithFinal.class) https://github.com/jayway/powermock/wiki/mockfinal

I would revisit the reason for doing this, you should refactor the test and not mock core java classes. Why is String class declared final in Java?

Community
  • 1
  • 1
chifer
  • 683
  • 5
  • 19
  • Thanks, I knew it's a final class, as I said `PowerMockito.mock(String.class)` I have already done that. – Jing Li Nov 19 '16 at 22:20
  • There is more setup before using PowerMockito.mock(String.class),you need to prepare.., also you can try partialMocking just that method https://github.com/jayway/powermock/wiki/MockPartial – chifer Nov 19 '16 at 22:48
  • Yes, I already had @PrepareForTest for my static and final classes, but it didn't work. – Jing Li Nov 19 '16 at 22:54