C’è un modo in JMockit per chiamare il metodo originale dal deriso metodo?

Nel mio mock classe, sto beffardo il metodo foo(). Per alcuni casi di test, voglio il finto attuazione di foo() per restituire un valore speciale. Per altri casi di test, voglio usare la reale attuazione di foo(). Ho un booleano definito nel mio mock classe in modo che io possa determinare nel mock metodo, se voglio restituire il valore speciale, o utilizzare il “vero” metodo. Il problema è che non riesco a capire come chiamare il metodo da schernito metodo.

Ho trovato che si può definire un membro speciale all’interno del finto oggetto denominato “it” (con il tipo di oggetto che viene deriso). Questo consente di fare riferimento a classe reale dal finto di attuazione. Così, il mio piano era, se ho bisogno di richiamare il “reale” attuazione di foo(), la farsa del metodo di chiamata.foo(). Tuttavia, questo non funziona, perchè la chiamata.foo() chiama semplicemente la versione finto di nuovo, non la versione reale, così finisco con una ricorsione infinita.

C’è qualche modo per fare questo lavoro?

EDIT: potrebbe essere più chiaro con un esempio di codice, ecco quello che il mio attuale deriso implementazione del metodo simile:

private RealClass it;
...
public SomeClass foo() {
    if(fakeIt) {
        return new SomeClass("fakevalue");
    } else {
        //doesn't work, just keeps calling the mock foo
        //in infinite recursion
        return it.foo();
    }
}

EDIT 2: Anche, per la maggior parte dei miei casi di test posso fare NON desidera che il finto attuazione. Quindi il mio primo tentativo di questo è stato solo chiamare Mockit.redefineMethods() all’interno di tali casi di test in cui avevo bisogno l’oggetto di simulazione. Ma questo non ha funzionato – a quanto pare si possono fare solo all’interno di installazione/smontaggio … il mio mock implementazione mai ho chiamato quando ho provato.

NOTE SULLA SOLUZIONE:

Prima di tutto io non credo che la risposta che ha funzionato, ma dopo aver giocato con un po ‘ di più, sembra che il problema è che mi è stato di miscelazione JMockit “core” metodi “annotazione” guidato metodi. A quanto pare quando si utilizza l’annotazione è necessario utilizzare Mockit.setupMocks, non Mockit.redefineMethods(). Questo è ciò che alla fine ha funzionato:

@Before 
public void setUp() throws Exception
{
    Mockit.setUpMocks(MyMockClass.class);
}

Quindi, per la falsa-classe:

@MockClass(realClass = RealClass.class)
public static class MyMockClass {
    private static boolean fakeIt = false;
    private RealClass it;

    @Mock(reentrant = true)
    public SomeClass foo() {
        if(fakeIt) {
            return new SomeClass("fakevalue");
        } else {
            return it.foo();
        }
    }
}

OriginaleL’autore Eric Asberry | 2008-12-10

3 Replies
  1. 7

    Penso che si può fare questo con l’ @Mock annotazione. Dal docs, @Mock(reentrant=true) sul tuo finto classe dovrebbe farlo.

    Vedere http://jmockit.googlecode.com/svn/trunk/www/javadoc/mockit/Mock.html

    Per esempio guarda qui http://jmockit.googlecode.com/svn/trunk/www/tutorial/StateBasedTesting.html#reentrant

    Non ho testato questo però..

    Devo essere perso qualcosa. Dai doc suona promettente, ma non sembra importa se io uso reentrent=true o false, ottengo lo stesso comportamento di prima. Anche il doc dice “per impostazione predefinita, tali chiamate non sono ammessi perché portano ad una ricorsione infinita …”, così mi sono confuso.
    Dopo un ulteriore esame, ho trovato quello che mi mancava 🙂
    Ho aggiornato il JavaDoc link e aggiunto un link esempio. +1 Per la risposta.
    I link sono rotti, come è stato più di 6 anni.
    Credo valga la pena di notare che questa risposta è valida solo indietro quando la domanda è stato risposto. Questo è stato deprecato in JMockit API nelle versioni più recenti di JMockit. La risposta data da Trevor Robinson è ora la risposta migliore, imo. Questa risposta è solo ancora valido se si sta utilizzando una vecchia versione di JMockit.

    OriginaleL’autore

  2. 5

    Nelle versioni più recenti di JMockit, Invocazione.procedere() può essere chiamato da un Modello attuazione. Vedere Fingere: di Procedere, in attuazione.

    public class MyMockClass extends MockUp<RealClass> {
    
        private static boolean fakeIt = false;
    
        @Mock
        public SomeClass foo(Invocation inv) {
            if (fakeIt) {
                return new SomeClass("fakevalue");
            } else {
                return inv.proceed();
            }
        }
    }

    OriginaleL’autore

  3. 1

    Invece di gettare un oggetto di simulazione si potrebbe anche sottoclasse l’oggetto che si desidera testare ed eseguire l’override dei metodi che dovrebbero restituire valori speciali.

    Per esempio:

    RealClass toTest = new RealClass(){
          public String foo(){
              return "special value";
          }
    }
    
    //use toTest in test

    Mantenendo questa definizione entro il test è chiaro anche per gli altri quali metodi vengono ‘beffato’.

    Grazie per il suggerimento! Unfortuntaely, non è possibile utilizzare questo approccio, perché la classe che sto beffardo, in realtà non viene creato direttamente da la prova caso. È stato creato da un oggetto che è sotto test.

    OriginaleL’autore

Lascia un commento