Anche se fondamentalmente d'accordo con la risposta di Nick Holt, ho pensato di sottolineare che mockito permette di fare ciò che si chiede con il seguente invito:
Foo mock = Mockito.mock(Foo.class, withSettings().extraInterfaces(Bar.class));
Ovviamente dovrete usare il cast: (Bar)mock
quando è necessario utilizzare il mock come Bar
ma che cast non sarà gettare ClassCastException
Ecco un esempio che è un po 'più completo, anche se del tutto assurda:
import static org.junit.Assert.fail;
import org.junit.Test;
import static org.mockito.Mockito.*;
import org.mockito.Mockito;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import org.hamcrest.Matchers;
import java.util.Iterator;
public class NonsensicalTest {
@Test
public void testRunnableIterator() {
// This test passes.
final Runnable runnable =
mock(Runnable.class, withSettings().extraInterfaces(Iterator.class));
final Iterator iterator = (Iterator) runnable;
when(iterator.next()).thenReturn("a", 2);
doThrow(new IllegalStateException()).when(runnable).run();
assertThat(iterator.next(), is(Matchers.<Object>equalTo("a")));
try {
runnable.run();
fail();
}
catch (IllegalStateException e) {
}
}
fonte
2009-08-13 08:14:18
Sono d'accordo con questo, ma per espandere: se stai usando Iniezione di dipendenza, e la tua classe ha bisogno sia di un Foo che di un Closable, dovresti davvero avere due setter separati per quelli. Se scegli di iniettare lo stesso oggetto per entrambi, allora è grandioso, ma penso che la classe sotto test non abbia bisogno di sapere che sono lo stesso oggetto - dovrebbe trattare il Foo as a Foo e il Closeable as a Closeable –
Nick, Matt, grazie per il tuo contributo. Giusto per chiarire lo scenario, il contesto è che Foo è un'interfaccia per un sistema modulare aggiuntivo. I moduli di terze parti implementano Foo e vengono quindi istanziati e utilizzati dal framework. Possono anche implementare Opzionalmente Closeable, nel qual caso il framework li chiuderà quando ha finito di usarli. Quindi, i test unitari devono coprire due scenari distinti: un Foo che è anche chiudibile e un Foo che non è Chiudibile. Spero che abbia senso. –
@NickHolt: non sarei completamente d'accordo con te. Considera il caso in cui hai un'interfaccia 'Persona' che ha solo getter (' getFirstName() ',' getAddress() ', ...) e l'interfaccia 'ModifiablePerson', che ha solo setter (' setFirstName() ',' setAddress() ', ...). E ora vuoi testare un SUT, che prende 'Person', ma controlla se ha superato l'oggetto' instanceof ModifiablePerson' e fa qualcosa in base a ciò. 'Closeable' è anche un buon esempio: se l'oggetto fornisce una funzionalità" estesa ", che è esplicitamente controllata da' instanceof' e sfruttata, cosa c'è di male in questo? –