Wie verspotten Sie das Lesen / Schreiben von Dateien über JUnit?

Hier ist mein Szenario

MyHandler.java

public abstract class MyHandler {

    private String path = //..path/to/file/here

    public synchronized void writeToFile(String infoText) {
        // Some processing
        // Writing to File Here
        File file = FileUtils.getFile(filepath);
        file.createNewFile();
        // file can't be written, throw FileWriteException
        if (file.canWrite()) {
            FileUtils.writeByteArrayToFile(file, infoText.getBytes(Charsets.UTF_8));
        } else {
            throw new FileWriteException();
        }
    }

    public String readFromFile() {
        // Reading from File here
        String infoText = "";
        File file = new File(path);
        // file can't be read, throw FileReadException
        if (file.canRead()) {
            infoText = FileUtils.readFileToString(file, Charsets.UTF_8);        
        } else {
            throw FileReadException();
        }

        return infoText
    }

}

MyHandlerTest.java

@RunWith(PowerMockRunner.class)
@PrepareForTest({
    MyHandler.class
})
public class MyHandlerTest {

    private static MyHandler handler = null;
    // Some Initialization for JUnit (i.e @Before, @BeforeClass, @After, etc)

    @Test(expected = FileWriteException.class)
    public void writeFileTest() throws Exception {

       handler.writeToFile("Test Write!");

    }

    @Test(expected = FileReadException.class)
    public void readFileTest() throws Exception {

       handler.readFromFile();

    }
}

In der obigen Quelle ist das Szenario, in dem die Datei nicht beschreibbar ist (Schreibberechtigung nicht zulässig), in Ordnung. Wenn ich jedoch versuche, ein Szenario auszuführen, in dem file nicht lesbar ist (Leseberechtigung nicht zulässig). Es hat immer die Datei gelesen, ich habe bereits versucht, die Dateiberechtigung für den Testcode über unten zu ändern

File f = new File("..path/to/file/here");
f.setReadable(false);

Ich habe jedoch etwas gelesen, setReadable() gibt immer false (fehlgeschlagen) zurück, wenn es auf einem Windows-Computer ausgeführt wird.

Gibt es eine Möglichkeit, die Dateiberechtigung der Zieldatei in Bezug auf JUnit programmgesteuert zu ändern?

Hinweis:

Der zu testende Zielquellcode kann nicht geändert werden Myhandler.class ist ein Legacy-Code, der nicht geändert werden darf.

3
lemoncodes 18 Jän. 2019 im 14:50

3 Antworten

Beste Antwort

Verwenden Sie PowerMock, um FileUtils.getFile (...) zu verspotten und eine Instanz von File (z. B. eine anonyme Unterklasse) zurückzugeben, die einen bestimmten Wert für canWrite () / canRead () zurückgibt, anstatt sich auf die Dateiberechtigungen des Betriebssystems zu verlassen.

Verspotten statischer Methoden mit Mockito

2
Torben 18 Jän. 2019 im 12:14

Da Mockito keine statischen Methoden verspotten kann, verwenden Sie stattdessen eine File Factory (oder überarbeiten Sie Ihre FileUtils als Factory). Sie können sie dann verspotten und auch eine verspottete File Instanz zurückgeben, wobei Sie können auch beliebige File Methoden verspotten.

Anstelle von FileUtils.getFile(filepath) haben Sie jetzt beispielsweise so etwas wie FileFactory.getInstance().getFile(filepath), wo Sie die getFile(String) -Methode leicht verspotten können.

0
m0skit0 18 Jän. 2019 im 12:29

In jUnit gibt es eine praktische Regel für Szenarien wie Ihre.

public class MyHandlerTest {

    @Rule
    // creates a temp folder that will be removed after each test
    public org.junit.rules.TemporaryFolder folder = new org.junit.rules.TemporaryFolder();

    private MyHandler handler;

    @Before
    public void setUp() throws Exception {
        File file = folder.newFile("myFile.txt");
        // do whatever you need with it - fill with test content and so on.
        handler = new MyHandler(file.getAbsolutePath()); // use the real thing
    }

    // Test whatever behaviour you need with a real file and predefined dataset.
}
0
SimY4 21 Jän. 2019 im 23:15