Brugerdefinerede svar og callbacks
Implementér brugerdefineret logik for mock-metodekald ved hjælp af `Answer`-interfaces for at simulere komplekse adfærdsmønstre.
Brugerdefinerede svar og callbacks er en gratis Mestrer test: JUnit, Mockito og integrationstest-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Mestrer test: JUnit, Mockito og integrationstest, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Mestrer test: JUnit, Mockito og integrationstest-kurset indeholder 4 lektioner i alt.
Mere end simpel stubbing
Nogle gange er det ikke nok blot at returnere en fast værdi med when().thenReturn() for dine mock-objekter.
- Hvad nu, hvis en mock-metode skal ændre et argument, der gives til den?
- Hvad nu, hvis den skal udføre en callback-funktion?
- Hvad nu, hvis returværdien afhænger af flere input på en kompleks og dynamisk måde?
Disse avancerede scenarier kræver tilpasset logik i dine mocks.
Introduktion til Mockitos Answer
Mockito leverer interfacet org.mockito.stubbing.Answer. Dette effektive værktøj lader dig definere tilpasset adfærd for et kald på en mock-metode.
- Tænk på det som at skrive et lille stykke kode, der køres, hver gang mock-metoden kaldes.
- Interfacet
Answerhar én metode:Object answer(Invocation invocation) throws Throwable;.
Det giver dig detaljeret kontrol over mocksvar.
Anatomien i answer()
Metoden answer() er det sted, hvor du implementerer din tilpassede logik. Den modtager et InvocationOnMock-objekt (ofte blot kaldet invocation).
- Objektet
InvocationOnMockindeholder vigtige oplysninger om metodekaldet:- Hvilken metode blev kaldt?
- Hvilke argumenter blev givet?
- Hvilket mock-objekt var involveret?
Du kan bruge disse oplysninger til at afgøre, hvad der skal returneres, kaste en undtagelse eller udføre sideeffekter.
Brug af doAnswer for fleksibilitet
Du kan bruge when().thenAnswer(), men Mockitos metode doAnswer() er ofte mere fleksibel og bruges bredt, især til void-metoder eller når den kombineres med andre stubs.
doAnswer()lader dig angive adfærd for et metodekald, før du definererwhen().- Den er især nyttig, når du skal:
- Opsamle argumenter.
- Kaldes callbacks.
- Ændre tilstanden for objekter, der gives som argumenter.
Tilpasset retur-logik
Lad os se, hvordan du bruger doAnswer til at returnere en værdi, der afhænger af inputargumentet. Her fordobler vores mock inputtallet.
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
// A simple interface to mock
interface Calculator {
int calculate(int input);
}
public class Main {
public static void main(String[] args) {
// Create a mock object for our Calculator interface
Calculator mockCalculator = Mockito.mock(Calculator.class);
// Define custom answer to double the input argument
Mockito.doAnswer(new Answer<Integer>() {
@Override
public Integer answer(InvocationOnMock invocation) throws Throwable {
// Get the first argument (index 0) as an Integer
Integer arg = invocation.getArgument(0);
return arg * 2; // Return double the argument
}
}).when(mockCalculator).calculate(Mockito.anyInt()); // Apply to any int input
// Test the custom behavior of the mock
System.out.println("Result for 5: " + mockCalculator.calculate(5));
System.out.println("Result for 10: " + mockCalculator.calculate(10));
}
}Simulering af callbacks
Et meget almindeligt og effektivt anvendelsesområde for doAnswer er simulering af asynkrone operationer eller kald af callbacks.
- Forestil dig en service, der modtager et
Callback-interface (for eksempel enConsumer) som argument. - Du kan bruge
doAnswertil manuelt at kalde callbackens metodeonSuccesselleronFailure.
Det lader dig teste, hvordan din programkode reagerer på forskellige callback-resultater uden faktisk asynkron udførelse.
Mocking af en callback
Her simulerer vi, at DataService kalder en Consumer-callback. doAnswer lader os udløse callbacken med en bestemt værdi, når fetchData kaldes.
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.function.Consumer;
// An interface representing a service that fetches data asynchronously
interface DataService {
void fetchData(String query, Consumer<String> callback);
}
public class Main {
public static void main(String[] args) {
DataService mockService = Mockito.mock(DataService.class);
// Configure the mock to simulate fetching data and calling the callback
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
// Get the arguments passed to fetchData
String query = invocation.getArgument(0); // The first argument is the query
Consumer<String> callback = invocation.getArgument(1); // The second is the callback
// Simulate a successful data fetch by invoking the callback
callback.accept("Data for '" + query + "' fetched successfully!");
return null; // Void methods in doAnswer return null
}
}).when(mockService).fetchData(Mockito.anyString(), Mockito.any(Consumer.class));
// Our application code would typically use this service
System.out.println("Application requesting user data...");
mockService.fetchData("user:456", result -> {
System.out.println("Application received data: " + result);
});
System.out.println("Application finished request setup.");
}
}Gå i dybden med Invocation
Objektet InvocationOnMock (eller blot invocation), der gives til din answer()-metode, er et effektivt kontekstobjekt.
invocation.getArguments(): Returnerer et array med alle argumenter, der blev givet til mock-metoden.invocation.getArgument(index): Returnerer et bestemt argument ud fra dets indeks.invocation.getMethod(): Giver dig detMethod-objekt, der blev kaldt, så du kan bruge reflection.invocation.getMock(): Returnerer selve mock-objektet.invocation.callRealMethod(): For spies lader dette dig kalde den faktiske metode.
Tip til brug af Answer
Tilpassede answers er effektive, men det er vigtigt at bruge dem med omtanke, så dine tests forbliver vedligeholdelsesvenlige og tydelige:
- Hold dem simple: Hvis din
answer-logik bliver for kompleks, kan det være tegn på et designproblem i din produktionskode eller en unødigt kompliceret testopsætning. - Foretræk enklere stubs: Vælg altid enklere stubmetoder som
thenReturn(),thenThrow()ellerthenCallRealMethod(), hvis de kan opnå den ønskede adfærd. - Test selve
Answer: Overvej ved meget komplekseAnswer-implementeringer at udtrække dem til en separat klasse og skrive en unit-test til den klasse.
Hvornår skal du bruge Answer
Her er typiske situationer, hvor interfacet Answer (som regel via doAnswer()) virkelig kommer til sin ret:
- Dynamiske returværdier: Når returværdien afhænger af inputargumenter på en ikke-triviel eller beregnet måde.
- Sideeffekter: Ændring af argumenter, der gives ved reference (for eksempel opdatering af et objekt).
- Callbacks: Udløsning af success- eller failure-callbacks for at simulere asynkrone operationer.
- Kædning af operationer: Simulering af en sekvens af interaktioner eller tilstandsændringer i ét mock-kald.
Tilpasset mock-adfærd
Du tester en UserService, der afhænger af en UserRepository. UserRepository har en metode save(User user), som typisk opdaterer brugerens ID, efter at den er gemt i en database.
Du vil mocke UserRepository for at simulere denne adfærd uden at oprette forbindelse til en rigtig database. Antag en User-klasse med setId(Long id).
Opsummering: Dynamiske mocks
Du har lært at tilføre dynamisk og kompleks adfærd til dine mocks ved hjælp af Mockitos Answer-interface og metoden doAnswer.
- Interfacet
Answerlader dig definere tilpasset logik, der udføres, når en mock-metode kaldes. - Objektet
InvocationOnMockgiver vigtig kontekst, herunder metodeargumenterne og selve mocken. doAnswerer velegnet til dynamiske returværdier, simulering af callbacks eller ændring af argumenter, der gives ved reference.
Husk at bruge `Answer` med omtanke og foretrække enklere stubs, når det er muligt, så dine tests forbliver tydelige og fokuserede.
Lær Mestrer test: JUnit, Mockito og integrationstest med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 12
- Lektioner
- 48
Ofte stillede spørgsmål
Er lektionen “Brugerdefinerede svar og callbacks” gratis?
Ja — alle 3 lektioner i læringssporet Mestrer test: JUnit, Mockito og integrationstest, inklusive “Brugerdefinerede svar og callbacks”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Mestrer test: JUnit, Mockito og integrationstest-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Brugerdefinerede svar og callbacks”?
Implementér brugerdefineret logik for mock-metodekald ved hjælp af `Answer`-interfaces for at simulere komplekse adfærdsmønstre. Du øver dig i Mestrer test: JUnit, Mockito og integrationstest med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Mestrer test: JUnit, Mockito og integrationstest?
Der kræves ingen tidligere erfaring. Mestrer test: JUnit, Mockito og integrationstest på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Brugerdefinerede svar og callbacks”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Mestrer test: JUnit, Mockito og integrationstest-lektion?
Ja. Alle Mestrer test: JUnit, Mockito og integrationstest-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Brugerdefinerede svar og callbacks
- Mocking af statiske metoder og konstruktører
- Bedste praksis for Mockito
- Indfangning af argumenter med ArgumentCaptor