Domanda

Sono un ragazzo di .NET e scrivo principalmente in C #.

Da C # 3.0, possiamo sfruttare le espressioni lambda e gli alberi delle espressioni per usare riflessione statica . Ad esempio, è possibile implementare GetMethodName nel seguente frammento per restituire il nome del metodo passato nel parametro:

string methodName = GetMethodName( o => o.DoSomething());
Console.WriteLine(methodName); // displays "DoSomething"

Ora, quando guardo i campioni di Mockito (o quelli di EasyMock) nel mondo Java, vedo:

LinkedList mockedList = mock(LinkedList.class);
when(mockedList.get(0)).thenReturn("first");

Come funziona?

Come funziona il metodo when ? Come interpreta mockedList.get (0) come una chiamata al metodo get con 0 passato come parametro e non come valore?

È stato utile?

Soluzione

Le librerie beffardo in genere non funzionano con gli alberi delle espressioni. Costruiscono un tipo che implementa l'interfaccia appropriata e risponde alle chiamate di metodo registrandole o convalidandole e restituendo le risposte preprogrammate. Questo di solito viene eseguito con un proxy (ad esempio RealProxy in .NET, Proxy in Java) o con generazione di codice dinamico.

Nel caso di EasyMock, utilizza Proxy (per interfacce, comunque), come puoi vedere nel codice sorgente: guarda org.easymock.internal.JavaProxyFactory .

Altri suggerimenti

Le librerie finte Java di solito funzionano così:

Quando crei un mock, viene creato un proxy effettivo (sia esso da un'interfaccia o una sottoclasse), l'istanza è in "modalità di registrazione". Ciò significa che viene registrata qualsiasi chiamata successiva (nome del metodo, parametri, ritorno previsto). Si noti che il proxy in modalità di registrazione non fa altro che registrare le chiamate. Non vi è alcuna riflessione in sé. Nessuna scoperta di metadati, ecc. Naturalmente queste librerie fanno alcuni trucchi (come la memorizzazione di invocazioni in una variabile thread-local per gestire metodi che restituiscono il vuoto) ma l'idea rimane la stessa.

Quindi, quando la modalità di riproduzione " " viene avviato, l'istanza finta verifica semplicemente le aspettative dall'elenco delle invocazioni (metodo + parametri e valori di ritorno).

Non ho mai lavorato con mockito o easymock ma non credo che la chiamata faccia quello che pensi che faccia. Non interpreta mockedList.get (0) in alcun modo speciale. Il metodo get viene eseguito normalmente sull'oggetto mockedList e il risultato viene consegnato a quando .

mockedList.get (0) è la sintassi di una chiamata al metodo e fa esattamente questo. Ciò che fa questo metodo non è esattamente chiaro. Il tipo di runtime di mockedList sarà una sottoclasse di LinkedList restituita dal metodo mock , che può essere implementato in qualunque modo il framework di derisione lo ritenga opportuno.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top