Je suis assez nouveau dans la moquerie et j'ai essayé de simuler le contenu réel (essentiellement créer un fichier virtuel dans la mémoire seule) afin qu'aucune donnée ne soit écrite sur le disque à aucun moment.
J'ai essayé des solutions comme se moquer du fichier et se moquer du plus grand nombre de propriétés que je peux comprendre autant que possible, puis l'écrire avec un fichier ou un tampon, mais celles-ci ne fonctionnent pas bien, car elles ont besoin de canoniques chemins. Quelqu'un a trouvé une solution autre que celle-ci ou similaire, mais que j'approche mal de cela?
Je l'ai fait comme ça:
private void mocking(){
File badHTML = mock(File.class);
//setting the properties of badHTML
when(badHTML.canExecute()).thenReturn(Boolean.FALSE);
when(badHTML.canRead()).thenReturn(Boolean.TRUE);
when(badHTML.canWrite()).thenReturn(Boolean.TRUE);
when(badHTML.compareTo(badHTML)).thenReturn(Integer.SIZE);
when(badHTML.delete()).thenReturn(Boolean.FALSE);
when(badHTML.getFreeSpace()).thenReturn(0l);
when(badHTML.getName()).thenReturn("bad.html");
when(badHTML.getParent()).thenReturn(null);
when(badHTML.getPath()).thenReturn("bad.html");
when(badHTML.getParentFile()).thenReturn(null);
when(badHTML.getTotalSpace()).thenReturn(0l);
when(badHTML.isAbsolute()).thenReturn(Boolean.FALSE);
when(badHTML.isDirectory()).thenReturn(Boolean.FALSE);
when(badHTML.isFile()).thenReturn(Boolean.TRUE);
when(badHTML.isHidden()).thenReturn(Boolean.FALSE);
when(badHTML.lastModified()).thenReturn(System.currentTimeMillis());
when(badHTML.mkdir()).thenReturn(Boolean.FALSE);
when(badHTML.mkdirs()).thenReturn(Boolean.FALSE);
when(badHTML.setReadOnly()).thenReturn(Boolean.FALSE);
when(badHTML.setExecutable(true)).thenReturn(Boolean.FALSE);
when(badHTML.setExecutable(false)).thenReturn(Boolean.TRUE);
when(badHTML.setReadOnly()).thenReturn(Boolean.FALSE);
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(badHTML));
/*
badHTMLText is a string with the contents i want to put into the file,
can be just about whatever you want
*/
bw.append(badHTMLText);
bw.close();
} catch (IOException ex) {
System.err.println(ex);
}
}
Toutes les idées ou conseils seraient très utiles. Quelque part après cela, j'essaie essentiellement de lire le fichier en utilisant une autre classe. J'essaierais de simuler une sorte de flux d'entrée, mais l'autre classe ne prend pas de flux d'entrée, car c'est la classe de gestion io pour le projet.
Vous semblez avoir des objectifs contradictoires. D'une part, vous essayez d'éviter d'écrire des données sur le disque, ce qui n'est pas un mauvais objectif dans les tests. De l'autre, vous essayez de tester votre classe de gestion des E/S, ce qui signifie que vous travaillerez avec des utilitaires système qui supposent que votre File
fonctionnera avec des appels natifs. En tant que tel, voici mes conseils:
File
. Mais ne le fais pas. Trop de choses natives en dépendent.File
et le transforme en Reader
, et la moitié qui analyse le HTML du Reader
.StringReader
pour simuler la source de données.N'ayez pas peur de refactoriser votre classe pour faciliter les tests, comme ici:
class YourClass {
public int method(File file) {
// do everything here, which is why it requires a mock
}
}
class YourRefactoredClass {
public int method(File file) {
return methodForTest(file.getName(), file.isFile(),
file.isAbsolute(), new FileReader(file));
}
/** For testing only. */
int methodForTest(
String name, boolean isFile, boolean isAbsolute, Reader fileContents) {
// actually do the calculation here
}
}
class YourTest {
@Test public int methodShouldParseBadHtml() {
YourRefactoredClass yrc = new YourRefactoredClass();
assertEquals(42, yrc.methodForTest(
"bad.html", true, false, new StringReader(badHTMLText));
}
}
À ce stade, la logique dans method
est si simple qu'elle ne vaut pas la peine d'être testée, et la logique dans methodForTest
est si facile d'accès que vous pouvez la tester intensivement.
Une façon de se moquer des appels d'E/S (avec Java 7 ce serait la classe finale NIO Java.nio.file.Files
)) Est d'encapsuler les appels nécessaires dans votre propre classe et de la simuler:
public class FileHelper {
public Path createDirectory(String directoryName) throws IOException {
return Files.createDirectory(Paths.get(directoryName));
}
public boolean exists(String name) throws IOException {
return Files.exists(Paths.get(name), LinkOption.NOFOLLOW_LINKS);
}
}
La logique métier se trouve dans le ImageManager
:
FileHelper fileHelperMock = Mockito.mock(new FileHelper());
ImageManager imageManager = new ImageManagerImpl(fileHelperMock);
Le test vérifiera l'appel à la méthode createDirectory()
sur votre maquette:
imageManager.save("directory");
Mockito.verify(fileHelperMock).createDirectory("directory");
J'utiliserais cette méthode pendant le développement piloté par les tests où je ne veux pas polluer les tests avec une gestion de fichiers réelle (par exemple, supprimer les répertoires/fichiers créés dans un bloc enfin dans chaque test unitaire).
Ensuite, j'aurais des tests d'acceptation couvrant tous les cas d'utilisation avec une véritable gestion des fichiers.