Unit testing with Mockito Portland Java User Group January 25, 2022
#java #mockito
Unit testingwith MockitoSean SullivanPortland Java User GroupJanuary 25, 2022
View Slide
Unit Tests
• Mockito library• Upgrading to Mockito 4• Extending Mockito• Anti-patterns
Mockito is a frameworkfor creating Mock objects
a Mock object mimics thebehavior of a real object
Gilt.comcheckout system
We wrote unit tests to verify:• happy path• edge case scenarios• error handling logic
• inventory reservation• payment system• shipping cost calculator• shipping restrictions• purchase limit service• tax calculator• discount calculatorGilt.com Checkout was dependent upon:
The test suite forGilt.com Checkoutused Mockito
We setup mock objects for:• Payment authorization• Inventory reservation• Discount redemption• Tax calculation• Shipping calculation
Maven pom.xmlorg.mockitomockito-core4.3.1test
import static org.mockito.Mockito.mock;import static org.mockito.Mockito.when;import static org.mockito.Mockito.verify;import static org.mockito.ArgumentMatcher.any;
TaxEngine taxEngine = mock(TaxEngine.class);ShippingCostCalculator shippingCalc = mock(ShippingCostCalculator.class);when(taxEngine.calculate(any())).thenReturn(new Money(5, USD));when(shippingCalc.calculate()).thenReturn(shippingInfo);
OrderManager unit testOrderManager manager = new OrderManager(taxEngine,shippingCalc);manager.sync(order);manager.submit(order);verify(taxEngine, once()).calculate(any());assertTrue(order.isSubmitted());
Mockito.when
thenReturn
How do I mimic afailure?
use thenThrow
TaxEngine taxEngine = mock(TaxEngine.class);when(taxEngine.calculate(any(), any())).thenThrow(new TaxViolationException());
Four major versions of Mockito• version 1.x• version 2.x• version 3.x• version 4.x
Upgrading toMockito 4.x
async-http-clientPR 1812
What ifmy company has500 Git repos?
Automatedrefactoring tool
OpenRewritehttps://moderne.io/
OpenRewrite
mockito.yml
Extending Mockito
Answer interfacepublic interface Answer {T answerInvocation(InvocationOnMock invocation);}
MockitoPlus library
MockitoPlus
MockitoPlusimport static org.mockito.Mockito.mock;import static io.github.mockitoplus.MockitoPlus.when;
MockitoPlusHelloWorld hello = mock(HelloWorld.class);when(hello.sayHello(any())).thenReturn("bonjour").failAlternatingInvocations();
MockitoPlusHelloWorld hello = mock(HelloWorld.class);when(hello.sayHello(any())).thenReturn("bonjour").firstInvocationFails();
MockitoPlusHelloWorld hello = mock(HelloWorld.class);when(hello.sayHello(any())).thenReturn("bonjour").intermittentFailures().randomDelay(Duration.of(500, MILLIS));Intermittent failureswith random delays
Mockito anti-patterns
// anti-patternList names = mock(List.class);// betterList names = new ArrayList();anti-pattern
// anti-patternOptional name = mock(Optional.class);// betterOptional name = Optional.of(“Obama”);anti-pattern
// anti-patternCompletableFuture f = mock(CompletableFuture.class);// betterCompletableFuture f = CompletableFuture.completedFuture(“bonjour”);anti-pattern
what about Scala?
“org.mockito” %% "mockito-scala" % “1.16.34” % Testbuild.sbt
import org.mockito.scalatest.MockitoSugarScala trait
Questions?
The End@tinyrobots