简体   繁体   中英

How to use mockito / powermockito to make an instantiated dependent class throw an exception on a specific method call

This is the code I want to test. It's pretty straight forward

  class FileHandler {
    public boolean deleteFiles(String path) {
      // mock this to throw an exception
    }
    public static FileHandler instatiateNew(String location) {
      // creates a FileHandler
    }
  }

  class B {
    public void action {
      try {
        FileHandler x = FileHandler.instantiateNew("asd");
        x.deleteFiles();
      } catch (Exception e) {
        // untested code I want to reach
      }
    }
  }

I now want to test method action and see how it handles x.deleteFiles() throwing an exception. I have tried doThrow, thenThrow and ran into errors (NullPointerException, probably because I stubbed the method wrongly) or the method not throwing the exception in the end.

I am also confused whether I need Powermockito or not. I will now try an approach, where I mock the whole FileHandler class. As I need to mock the static instantiation method I will need PowerMock for that. But I would prefer a less heavy handed solution. Does it exist?

my partial class mock is now:

FileHandler mockHandler = Mockito.mock(FileHandler.class)
Mockito.mock(mockHandler.deleteFiles(Mockito.anyString()).thenThrow(Exception.class);
PowerMockito.mockStatic(FileHandler.class);
PowerMockito.when(FileHandler.instantiateNew(Mockito.anyString())).thenReturn(mockHandler())

Which is still causing issues, maybe becasue FileHandler is used elsewhere and mockStatic kills all other usages.

Make sure all the necessary members are properly arranged so that the test can be exercised.

For example

RunWith(PowerMockRunner.class)
@PrepareForTest({FileHandler.class})
public class MyTestCase {
    public void testdeleteFilesErrorHandling() throws Exception {
        //Arrange
        //instance mock
        FileHandler handler = Mockito.mock(FileHandler.class);
        Mockito.when(handler.deleteFiles(anyString())).thenThrow(new Exception("error message"));
        //mock static call
        PowerMockito.mockStatic(FileHandler.class);
        Mockito.when(FileHandler.instantiateNew(anyString())).thenReturn(handler);
        
        B subject = new B();
        
        //Act
        subject.action();
        
        //Assert
        //perform assertion
    }
}

Reference: Using PowerMock with Mockito

using mockStatic was not an option for me as FileHandler was used in setup and teardown of the tests and this heavy handed approach would cause problems.

What saved me where stub and method from org.powermock.api.support.membermodification.MemberModifier .

FileHandler mock = Mockito.mock(FileHandler.class);
Mockito.when(mock.deleteFiles(anyString()))
    .thenThrow(Exception.class);

stub(method(FileHandler.class, "instantiateNew", String.class)).toReturn(mock);

Note that it is necessary to prepare class FileHandler through a test class decorator and to use the PowerMockRunner. This is necessary as we are stubbing a static method on FileHandler. This is done so:

@PrepareForTest({FileHandler.class})
@RunWith(PowerMockRunner.class)
public class MyTest extends MyBaseTestClass {
    @Test
    public void myTest() {
        // write test code from above here.
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM