4

I have class to test like below:

public class ReportWriter {
    private FileWrter fw; 
    private static Logger logger = Logger.getLogger(ReportWriter.class); 
    public ReportWriter(FileWrter fw) {
        this.fw = fw;
    } 
    public void writeData(Data) {
        try{
            fw.open();
            fw.write(data);
            fw.close();
        } **catch(DiskFullException e) {
            //after catch we log and handle it without rethrow the exception
            logger.log(Level.WARN, "warning log here", e);
            // some more logic here
            sendEmailToSupport();
        }**
    } 
}

The question is how to test the logic in catch block?

Eric
  • 1,031
  • 4
  • 14
  • 29

1 Answers1

3

If the sendEmailToSupport is at least a package level method, then you could go for something like:

public class ReportWriterClass{

   @Spy
   @InjectMocks
   private ReportWriter reportWriterSpy;

   @Mock
   private FileWrter fwMock;

   @Before
   public void init(){
       MockitoAnnotations.initMocks(this);
   }

   @Test
   public void shouldSendEmail_whenDiskIsFull() throws Exception{
       // Arrange
       Data data = new Data();

       doNothing().when(reportWriterSpy).sendEmailToSupport());
       doThrow(new DiskFullException()).when(fwMock).write(data);

       // Act
       reportWriterSpy.writeData(data);

      // Assert
      verify(reportWriterSpy).sendEmailToSupport();
   }
}
Maciej Kowalski
  • 25,605
  • 12
  • 54
  • 63
  • looks really neat! Can you explain more on "doThrow(new DiskFullException()).when(fwMock).write(data);" instead of "when(fwMock).write(data).thenThrow(new DiskFullException());" – Eric Jun 15 '17 at 14:43
  • In case of a Mock its a matter of preference. When stubbing a Spy you have to use the doXXX variation in order for the real implementation to not get invoked while setting up. – Maciej Kowalski Jun 15 '17 at 14:59
  • There's actually one more reason to use the `doThrow(new DiskFullException()).when(fwMock).write(data)`: if the method of the mock you want to test has the return type `void`, you must use this notation as the other one (`when(fwMock.write(data)).thenThrow(new DiskFullException())`) will not allow void methods inside `when`. – Voronin Mar 19 '22 at 02:42