Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito mock calling real method implementation when attempting to stub package protected method

Tags:

java

mockito

I'm trying to stub a method using Mockito 1.8.5, but doing so calls the real method implementation (with "" as parm values) which throws an exception.

package background.internal; //located in trunk/tests/java/background/internal  public class MoveStepTest {      @Test     public void testMoveUpdate() {         final String returnValue = "value";         final FileAttachmentContainer file = mock(FileAttachmentContainer.class);         doReturn(returnValue).when(file).moveAttachment(anyString(), anyString(), anyString());         //this also fails         //when(file.moveAttachment(anyString(), anyString(), anyString())).thenReturn(returnValue);          final AttachmentMoveStep move = new AttachmentMoveStep(file);         final Action moveResult = move.advance(1, mock(Context.class));         assertEquals(Action.done, moveResult);     } } 

The method I'm trying to mock looks like this. There are no final method or classes.

package background.internal; //located in trunk/src/background/internal      public class FileAttachmentContainer {         String moveAttachment(final String arg1, final String arg2, final String arg3)                  throws CustomException {             ...         }          String getPersistedValue(final Context context) {            ...              }     } 

And the class I'm passing the mock looks like this:

package background.internal; //located in trunk/src/background/internal public class AttachmentMoveStep {      private final FileAttachmentContainer file;      public AttachmentMoveStep(final FileAttachmentContainer file) {         this.file = file;             }      public Action advance(final double acceleration, final Context context) {         try {             final String attachmentValue = this.file.getPersistedValue(context);             final String entryId = this.file.moveAttachment(attachmentValue, "attachment", context.getUserName());              //do some other stuff with entryId         } catch (CustomException e) {             e.log(context);         }             return Action.done;     } } 

What is causing the real implementation to be invoked and how can I prevent it?

like image 562
Jake Walsh Avatar asked Aug 16 '12 23:08

Jake Walsh


1 Answers

The method you are mocking is not accessible to the Mockito code.

Because your test code and your code under test are in the same package, the compiler lets you set up your mock that way, but at runtime, the Mockito library has to try to access moveAttachment, but it's not working in your case. This appears to be a bug or known limitation in Mockito as it should support that case, (and in fact, does support it in most cases).

The easiest thing to do would be to make moveAttachment a public method. If that is not an option, then first question whether you want to even mock it. What happens if the real method gets called?

The last option is to use PowerMock to treat the moveAttachment method as a private method and mock it that way.

like image 188
jhericks Avatar answered Sep 19 '22 11:09

jhericks