web-dev-qa-db-fra.com

powermock mocking constructeur via whennew () ne fonctionne pas avec la classe anonyme

J'ai une classe DummyResource et un fichier DummyTarget, ainsi qu'une classe de test TestDummyResource comme ci-dessous, mais l'objet fictif DummyResource dr = mock(DummyResource.class) ne fonctionne que lorsque j'appelle le constructeur dans une classe normale. en utilisant l'objet simulé.

Versions:

powermock 1.4.12 mockito 1.9.0 junit 4.8.2

DummyTarget.Java:

import Java.io.IOException;
import Java.io.OutputStream;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;


public class DummyTarget {
    public StreamingOutput testMocking() {
        return new StreamingOutput() {
            @Override
            public void write(OutputStream arg0) throws IOException, WebApplicationException {
                new DummyResource();
            }
        };
    }
}

DummyResource.Java:

package com.smin.dummy;

public class DummyResource {
    public DummyResource() {
        System.out.println("mock failure");
    }
}

TestDummyResource.Java:

package com.smin.dummy;

import static org.mockito.Mockito.mock;

import Java.io.IOException;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest({DummyResource.class,DummyTarget.class})
public class TestDummyResource  {

    @Before
    public void setUp() throws Exception {
        DummyResource dr = mock(DummyResource.class);
        PowerMockito.whenNew(DummyResource.class).withNoArguments().thenReturn(dr);
    }

    @Test
    public void testMocked() throws WebApplicationException, IOException {
        new DummyResource(); // it uses the mocked object dr here, 
                             //doesn't print "mock failure"
        StreamingOutput sop = new DummyTarget().testMocking();
        sop.write(null);     // it calls DummyResource's constructor,
                             // prints ""mock failure"" here
    }
}
19
Shengjie

Il semble qu'une classe anonyme puisse hériter du package de la classe qui la définit. Pouvez-vous essayer la forme générique de PrepareForTest ?:

@PrepareForTest("com.smin.dummy.*")

Si cela ne fonctionne pas, vous pouvez essayer le fusil de chasse PrepareEverythingForTest Annotation.

11
Brian Henry

Vous devez avoir préparé la classe appelant le constructeur, et non la classe sur laquelle le constructeur est appelé, les éléments suivants devraient vous aider:

@PrepareForTest(DummyTarget.class)

Pour plus d'informations, consultez this page.

35
zbrunson

En fait, vous devez préparer pour tester la classe qui appelle le constructeur, et non la classe sur laquelle le constructeur a été appelé. Voir https://github.com/jayway/powermock/wiki/MockConstructor .

Dans votre cas, vous devez utiliser @PrepareForTest (DummyTarget.class).

9
Hamilton Rodrigues

J'ai eu le même problème et je l'ai résolu en utilisant whenNew avec un nom complet. Le nom qualifié complet d'une classe anonyme interne dans votre cas est:

DummyTarget.class + "$1"

vous devriez donc créer une maquette de cette classe:

DummyResource dr = mock(Class.forName(DummyTarget.class + "$1"));

et cela fonctionnera pour vous.

De plus, n'oubliez pas de préparer le cours DummyTarget:

@PrepareForTest(DummyTarget.class)

J'espère que ça a aidé =]

0
Slava Shpitalny