Soy bastante nuevo para burlarse, y he estado tratando de burlarse de los contenidos reales (básicamente, crear un archivo virtual en la memoria solo) por lo que los datos no se escriben en el disco en cualquier momento.

He intentado las soluciones como burlándose de el archivo y se burla de como muchas de las propiedades que puedo averiguar tanto como sea posible y, a continuación, también escrito en ella con un filewriter/bufferedwriter, pero los que no funcionan bien, ya que ellos necesitan canónica de caminos. Cualquiera que se encuentre una solución que no sea de este o similar, pero de que me estoy acercando esta mal?

He estado haciendo como este:

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);
}
}

Cualquier idea u orientación sería muy útil.
En algún lugar después de esto yo, básicamente, intentar leer el archivo utilizando otra clase. Me gustaría tratar de burlarse de algún tipo de señal de entrada, pero la otra clase no tomar un inputstream, ya que es el io de manejo de clase para el proyecto.

  • ¿Cuál es el objetivo de la prueba? ¿Por qué no se burlan de la BufferedWriter?
  • BufferedWriter era escribir archivos en el archivo de modo que el burlaban de archivo podría ser procesado por otra clase. La otra prueba es para probar y calificar el contenido del archivo html.
  • En lugar de burlarse de Archivo, intente espía(Archivo nuevo(…)). A continuación, puede cuando() sólo el comportamiento que usted realmente quiere cambiar, en lugar de tener que lidiar con la API completa.
  • NO se burlan o espiar un Archivo! Esto no es la forma correcta de hacerlo. Es una de las pruebas anti-patrón. Más en general no se burlan de los tipos que no son tuyos!. En lugar de centrarse en una división de la funcionalidad entre el código de acceso del archivo y el código que procesar el contenido. Jeff respuesta es el camino a seguir !
  • Yo diría que la más absoluta puede (y debe, bajo ciertas circunstancias) simulacros de código que no es propia -, PERO SÓLO las interfaces! El código debe estar trabajando en contra de las interfaces de todos modos, no de implementaciones concretas, en lo posible. java.io.Archivo no cumple con el requisito de interfaz de aunque. Tan MAL candidato para la burla.

2 Comentarios

  1. 62

    Parece ser después de objetivos contradictorios. Por un lado, usted está tratando de evitar la escritura de datos en el disco, que no es un mal objetivo de las pruebas. Por el otro, está tratando de poner a prueba su I/O-manejo de la clase, lo que significa que vamos a estar trabajando con las utilidades del sistema que asumir que su File va a trabajar de forma nativa con las llamadas. Como tal, este es mi guía:

    • No trate de burlarse de una File. Simplemente no. Demasiado muchos nativos de las cosas dependen de él.
    • Si usted puede, dividir el I/O código de control en la mitad de la que se abre un File y se convierte en un Reader, y la mitad de la que se analiza HTML fuera de la Reader.
    • En ese punto, usted no necesita un simulacro–simplemente construir un StringReader para simular el origen de datos.
    • Mientras que se encarga de su unidad de pruebas bastante bien, puede que también desee escribir un de pruebas de integración que utiliza un archivo temporal y asegurar que la lectura es a la derecha. (Gracias Brice para añadir que la punta!)

    No tenga miedo a refactorizar su clase para hacer la prueba más fácil, como aquí:

    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));
    }   
    }   

    En este punto la lógica en method es tan sencillo, no vale la pena probar,
    y la lógica en methodForTest es de fácil acceso que usted puede probar mucho.

    • +1 para no burlarse de un archivo y la división de la lógica en los diferentes objetos con diferentes preocupaciones. También de manera más general, no es en absoluto una buena idea para burlarse de los tipos que no posee. Así que me estoy replanteando lo que dijo Jeff, pero escribir una test de integración que hará valer el código que se puede abrir y/o escribir el archivo y proporcionar su propio tipo o un Reader/Writer y se escribe a unidad de prueba para el código que se va a procesar el contenido, por supuesto, usted no tiene que burlarse de la Reader/Writer pero el uso o afirmar que el contenido en las implementaciones existentes como el StringReader/StringWriter.
    • Sí, eso es lo que yo haría si pudiera editar toda la manera abajo. Me técnicamente puede editar, pero no puede porque podría romper la presente facilidad de uso para otros.
    • Matt-como con method anteriormente, a menudo se puede insertar su propia prueba de acceso sin cambiar la API externa. Entiendo que puede que no sea su parte del proyecto, pero si tu trabajo es prueba de que alguien más duro-a-clase de prueba, que generalmente vale la pena probar a mover las cosas para hacerlo más limpio y más fácil. Buena suerte! 🙂
    • Gracias. Decidí pasar de ella por completo y ni siquiera tratar de burlarse de estos, y sólo tienes que utilizar archivos reales, ya que tratando de burlarse de algo o de sustituir nada se interpuso en el camino del resto de la obra.
    • Cómo sobre el uso de un sistema de archivos virtual, tales como JIMFS? Cuando pruebo un servicio que copias un archivo de formulario de la a a la B y me deja copiar dentro del sistema de archivos virtual, es que sigue siendo una unidad de prueba? es que en absoluto una buena idea?
    • Inteligente! Eso es probablemente muy bien, teniendo en cuenta que el NIO fue diseñado para que la capa de abstracción adicional que java.io.Archivo normalmente carece. Acaba de darse cuenta de que es no es una gota en el reemplazo y de que burlarse de NIO clases es todavía una mala idea prestados innecesaria en el comportamiento de la memoria. Yo todavía me llaman de una unidad de prueba, pero se los dejo para los filósofos.

  2. 4

    Una manera de burlarse de llamadas de e/S (con Java 7 sería el NIO final de la clase java.nio.file.Files) es envolver la necesaria llamadas en su propia clase y burlarse de ella:

    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 lógica de negocio se encuentra en la ImageManager:

    FileHelper fileHelperMock = Mockito.mock(new FileHelper());
    ImageManager imageManager = new ImageManagerImpl(fileHelperMock);

    La prueba se verifica que la llamada a createDirectory() método en su simulacro:

    imageManager.save("directory");
    Mockito.verify(fileHelperMock).createDirectory("directory");

    Me gustaría utilizar este método durante el desarrollo basado en pruebas donde no quiero contaminar las pruebas con el real archivo de gestión (por ejemplo, eliminar creado los directorios/archivos en un bloque finally en cada unidad de prueba).

    Entonces tendría pruebas de aceptación, abarcando cada caso de uso real de manejo de archivos.

Dejar respuesta

Please enter your comment!
Please enter your name here