Reputation: 359
The below code is to write the content to the file .
public String saveSecretToFile() {
File file = new File("test.txt");
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
writer.write(secretValue);//secretValue is the content
} catch (IOException e) {
LOGGER.error("Error writing to file: {}", e.getMessage());
}
}
The catch block is not covered in JUnit Test case.
@InjectMocks
private MyHelper myHelper;
try (MockedStatic<FileOutputStream> mockedStatic = Mockito.mockStatic(FileOutputStream.class)) {
FileWriter mockFile = mock(FileWriter.class);
OutputStream mockFileWriter = Mockito.spy(new FileOutputStream(String.valueOf(mockFile)));
doThrow(new IOException("IO error")).when(mockFileWriter).write(anyString().getBytes());
IOException thrown = assertThrows(IOException.class, () -> myHelper.saveToFile("secretName"));
}
I have read that , mocking BufferedWriter won't work as the internal OutputStream of FileWriter should be mocked. The expected result of the unitest case is to throw the exception. But, the result is shown as java.lang.AssertionError: expected java.io.IOException to be thrown, but nothing was thrown
Upvotes: 0
Views: 36
Reputation: 628
I would do something like this :
1- First implement the write to mock.
public class MyHelper {
private final BufferedWriter writer;
// Constructor for dependency injection
public MyHelper(BufferedWriter writer) {
this.writer = writer;
}
public void saveSecretToFile(String secretValue) {
try {
writer.write(secretValue);
writer.flush();
} catch (IOException e) {
LOGGER.error("Error writing to file: {}", e.getMessage());
throw new RuntimeException("Error writing to file", e); // Throw to signify error
}
}
}
2- Write both tests to happy path and unhappy path with IOException using mock of my previous service, and check that method is called.
There is a verify which check that method has been called.
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import java.io.BufferedWriter;
import java.io.IOException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.*;
class MyHelperTest {
@Mock
private BufferedWriter mockWriter;
@InjectMocks
private MyHelper myHelper;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void testSaveSecretToFile_Success() throws IOException {
// Arrange
String secretValue = "secret";
// Act
myHelper.saveSecretToFile(secretValue);
// Assert
verify(mockWriter, times(1)).write(secretValue);
verify(mockWriter, times(1)).flush();
}
@Test
void testSaveSecretToFile_ThrowsException() throws IOException {
// Arrange
String secretValue = "secret";
doThrow(new IOException("IO error")).when(mockWriter).write(anyString());
// Act & Assert
Exception exception = assertThrows(RuntimeException.class, () -> myHelper.saveSecretToFile(secretValue));
assertTrue(exception.getCause() instanceof IOException);
assertEquals("Error writing to file", exception.getMessage());
verify(mockWriter, times(1)).write(secretValue); // Verify write was called before exception
}
}
Upvotes: 0