web-dev-qa-db-fra.com

Mocking Java InputStream

Veuillez fournir des pointeurs pour m'aider à me moquer de cet objet Java InputStream. Ceci est la ligne de code que je souhaiterais me moquer:

InputStreamReader inputData = new InputStreamReader(System.in);
bufferdReader = new BufferedReader(inputData);
bufferdReader.readLine(); 
52
Reji
BufferedReader bufferedReader = org.mockito.Mockito.mock(BufferedReader.class);
when(bufferedReader.readLine()).thenReturn("first line").thenReturn("second line");

org.junit.Assert.when(new Client(bufferedReader).parseLine()).thenEquals(IsEqual.equalTo("1"));
44
Boris Pavlović

Vous pouvez utiliser commons-io pour créer des flux d'entrée de stub:

InputStream stubInputStream = 
     IOUtils.toInputStream("some test data for my input stream", "UTF-8");
87
Eric

Vous pouvez simplement utiliser un ByteArrayInputStream et le remplir avec vos données de test.

@ Exemple de Brad dans les commentaires:

InputStream anyInputStream = new ByteArrayInputStream("test data".getBytes());
76
pap

Je ne suis pas d'accord avec la réponse choisie pour cette question. Les frameworks de mocking comme Mockito sont agréables et tous, cependant, lorsque l'API standard Java api est disponible, vous pouvez envisager de l'utiliser à la place.

c'est à dire.

BufferedReader reader = new BufferedReader(new StringReader("some string"));

Pourquoi utiliser un objet Mock dans vos classes de test alors que vous pouvez en utiliser un réel avec tout son état et son comportement?

Pour en savoir plus sur la façon dont cela fonctionne, vous pouvez rechercher le modèle de conception "décorateur".

16
John Deverall
@Test
    public void testReadFile() {
    TestClass ClassName = Mockito.mock(TestClass.class);
     InputStream in = Mockito.mock(InputStream.class);
     InputStreamReader inr =Mockito.mock(InputStreamReader.class);
     BufferedReader bufferedReader =Mockito.mock(BufferedReader.class);
       try {
         PowerMockito.whenNew(InputStreamReader.class).withArguments(in).thenReturn(inr);
         PowerMockito.whenNew(BufferedReader.class).withArguments(inr).thenReturn(bufferedReader);
         String line1 = "example line";
         PowerMockito.when(bufferedReader.readLine()).thenReturn(line1).thenReturn(null);
         method return type = Whitebox.invokeMethod(ClassName, "MethodName", arguement);
         assertEquals("result is::","expected", actual);
     } catch (Exception e) {
         e.printStackTrace();
     }
 }
2
Pentayya

Changez votre objet pour qu'il soit plus facile à tester, quelque chose comme ceci:

public MyObject {
    private InputStream inputStream;

    public void setInputStream(InputStream inputStream) {this.inputStream = inputStream;}

    public void whatever() {
        InputStreamReader inputData = new InputStreamReader(inputStream);
        bufferdReader = new BufferedReader(inputData);
        bufferdReader.readLine(); 
    }
}

puis lorsque vous utilisez votre objet initialisez d'abord son inputStream:

MyObject myObject = new MyObject();
myObject.setInputStream(System.in);

Vous avez maintenant un objet où vous pouvez le tester en utilisant n'importe quelle implémentation de InputStream que vous souhaitez (ByteArrayInputStream est un bon à essayer).

2
Nathan Hughes
String testString = "test\nstring";
InputStream stream = new ByteArrayInputStream(testString.getBytes(StandardCharsets.UTF_8));

BufferedReader reader = new BufferedReader(new InputStreamReader(stream));

Assert.assertEquals("test", reader.readLine());
Assert.assertEquals("string", reader.readLine());
2
eyveer

La meilleure solution que j'ai trouvée est d'utiliser

final InputStream inputStream1 = IOUtils.toInputStream("yourdata");

puis envelopper le flux d'entrée dans bufferedReader meilleure façon d'écrire le test autour du flux d'entrée

1
Pritesh

En supposant que vous utilisez Maven, vous pouvez placer une ressource dans le dossier "src/test/resources /", disons "src/test/resources/wonderful-mock-data.xml". Alors en vous jUnit vous pouvez faire:

    String resourceInputFile = "/database-insert-test.xml";
    URL url = this.getClass().getResource(resourceInputFile);
    Assert.assertNotNull("Can't find resource " + resourceInputFile, url);

    InputStream inputStream = url.openStream();

    // Now you can just use the inputStream for method calls requiring this param
    (...)

Dans cet exemple, le varialble url sera null si la ressource donnée ne peut pas être trouvée dans le chemin de classe actuel. Cette approche vous permet de placer plusieurs scénarios dans différents resourceInputFile (s). ) sont normalement disponibles en tant que ressources de chemin de classe à partir de tous les tests jUnit.

0
A. Masson