Search code examples
javajunitpowermockeasymockpowermockito

How can I surpass or skip a method using JUNIT?


I have a block of code for which I need to test .Lets say

Class MainClass{    
   public void startProcess() {     
      ----Some Logic to generate fileName; 
          uploadFile(fileName);     
       }

  private static void uploadFile(String key) {    
      fileUpload();    
      deleteFile();    
  }    
}

I want to write a JUNIT test which will call startProcess but either skip the uploadFile line or just ignore any lines present in uploadFile method .

I tried to use powerMock but it doesnt work . Below is my code

@RunWith(PowerMockRunner.class)
@PrepareForTest(MainClass.class)
public class MainClassTest {         
   @Test
   public void teststartProcess() throws Exception {
     processor=PowerMock.createPartialMock(MainClass.class,"uploadFile");
     PowerMock.expectPrivate(processor , "uploadFile", "xyz").andAnswer(
       new IAnswer<Void>() {
       @Override
       public Void answer() throws Throwable {
         System.out.println("Invoked!");
         return null;
       }
    }).atLeastOnce();
  }
}

But it does't override the method uploadFile to just print invoked . It calls fileUpload and deleteFile instead of just skipping the lines and print invoke .

My basic goal is to mock the method uploadFile to just print

private void uploadFile(String key) {
  System.out.println("Invoked");
}

I know it's possible using Mockito but we can use either PowerMock or EasyMock .


Solution

  • Instead of trying to go the way with over complicated tests you should consider to refactor your code so that it is testable. From what you provided I would move the file functionality to another class. something like this:

    public class MainClass {
        private final FileUploader fileUploader;
    
        public MainClass(FileUploader fileUploader) {
            this.fileUploader= fileUploader;
        }
    
        public void startProcess() {
            fileUploader.uploadFile(fileName);
        }
    }
    

    With this refactoring you gain the possibility to use plain mocking for the test:

    String fileName = "foo";
    FileUploader fileUploader = mock(FileUploader.class);
    
    MainClass classUnderTest = new MainClass(fileUploader);
    classUnderTest.startProcess();
    
    verify(fileUploader, times(1)).uploadFile(fileName);
    

    An additional benefit is that testing the fileUploader becomes also easy. As you can see I also got rid of all the complicated Partial mocking and private testing.