Post on 15-Apr-2017
transcript
M O C K S , S T U B S A N DF A K E S .
¿ W H A T E L S E ?.
A L E X S O T O B - L O R D O F T H E J A R S . C O M
alexsotoblordofthejars
alexsotoblordofthejars
CommitStage
C O N T I N U O U SI N T E G R A T I O N
alexsotoblordofthejars
U N I T T E S T S
Fast,Isolated,Repeteable,Self-Validating,Timely
F I R S T
A P P L I C A T I O N S A R E C O M P L E X
T E S T D O U B L E
alexsotoblordofthejars
M O C K S
alexsotoblordofthejars
M O C K SPre-programmedwithexpectations
alexsotoblordofthejars
M O C K SPre-programmedwithexpectations
BehaviorVerification
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
Easytowrite
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
EasytowriteVersatile
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
EasytowriteVersatile
Mockito,EasyMock,jMock
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
EasytowriteVersatile
Mockito,EasyMock,jMockVerbose
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
EasytowriteVersatile
Mockito,EasyMock,jMockVerbose
ReimplementingBusiness
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
EasytowriteVersatile
Mockito,EasyMock,jMockVerbose
ReimplementingBusinessNostate
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
EasytowriteVersatile
Mockito,EasyMock,jMockVerbose
ReimplementingBusinessNostate
Noexecutingfullstack
alexsotoblordofthejars
testCompiletestCompile(('org.mockito:mockito-all:1.10.19''org.mockito:mockito-all:1.10.19')){{
excludegroupexcludegroup::'org.hamcrest''org.hamcrest'
}}
D E P E N D E N C I E S
alexsotoblordofthejars
@@RunWithRunWith((MockitoJUnitRunnerMockitoJUnitRunner..classclass))
publicpublicclassclassTestTest{{
@MockEmailServiceemail@MockEmailServiceemail;;
}}
publicpublicclassclassTestTest{{
@MockEmailServiceemail@MockEmailServiceemail;;
@Before@Beforepublicpublicvoidvoidbeforebefore(()){{
MockitoAnnotationsMockitoAnnotations..initMocksinitMocks((thisthis))
}}
}}
EmailServiceemailServiceEmailServiceemailService==MockitoMockito..mockmock((EmailServiceEmailService..classclass));;
I N I T
alexsotoblordofthejars
MockitoMockito..whenwhen((emailemail..receiveBodyMessagesWithSubjectreceiveBodyMessagesWithSubject(("MySubject""MySubject"))))..thenReturnthenReturn(("ThisisMyMessage""ThisisMyMessage"))
SystemSystem..outout..printlnprintln((emailemail..receiveBodyMessagesWithSubjectreceiveBodyMessagesWithSubject(("Wrongsubject""Wrongsubject"))));;
SystemSystem..outout..printlnprintln((emailemail..receiveBodyMessagesWithSubjectreceiveBodyMessagesWithSubject(("MySubject""MySubject"))));;
SystemSystem..outout..printlnprintln((emailemail..receiveBodyMessagesWithSubjectreceiveBodyMessagesWithSubject(("MySubject""MySubject"))));;
E X A M P L E
alexsotoblordofthejars
MockitoMockito..whenwhen((emailemail..receiveBodyMessagesWithSubjectreceiveBodyMessagesWithSubject((MatchersMatchers..anyStringanyString(())))))..thenReturnthenReturn(("ThisisMyMessage""ThisisMyMessage"));;
SystemSystem..outout..printlnprintln((emailemail..receiveBodyMessagesWithSubjectreceiveBodyMessagesWithSubject(("Subject""Subject"))));;
E X A M P L E W I T H A N Y
alexsotoblordofthejars
InvoiceServiceinvoiceServiceInvoiceServiceinvoiceService==newnewInvoiceServiceInvoiceService((emailemail));;
invoiceServiceinvoiceService..sendsend(());;
MockitoMockito..verifyverify((emailemail,,MockitoMockito..timestimes((11))))..sendMessagesendMessage((MatchersMatchers..anyStringanyString(()),,MatchersMatchers..anyStringanyString(())));;
E X A M P L E V E R I F Y
alexsotoblordofthejars
InvoiceServiceinvoiceServiceInvoiceServiceinvoiceService==newnewInvoiceServiceInvoiceService((emailemail));;
invoiceServiceinvoiceService..sendsend(());;
ArgumentCaptorargumentArgumentCaptorargument==ArgumentCaptorArgumentCaptor..forClassforClass((StringString..classclass));;
MockitoMockito..verifyverify((emailemail,,MockitoMockito..timestimes((11))))..sendMessagesendMessage((argumentargument..capturecapture(()),,MatchersMatchers..anyStringanyString(())));;
AssertAssert..assertThatassertThat((argumentargument..getValuegetValue(()),,CoreMatchersCoreMatchers..startsWithstartsWith(("Invoice:""Invoice:"))));;
E X A M P L E A R G U M E N T C A P T O R
alexsotoblordofthejars
EmailServiceemailEmailServiceemail==newnewEmailServiceEmailService(());;
EmailServicespyEmailEmailServicespyEmail==MockitoMockito..spyspy((emailemail));;
InvoiceServiceinvoiceServiceInvoiceServiceinvoiceService==newnewInvoiceServiceInvoiceService((spyEmailspyEmail));;
invoiceServiceinvoiceService..sendsend(());;
MockitoMockito..verifyverify((spyEmailspyEmail,,MockitoMockito..timestimes((11))))..sendMessagesendMessage((argumentargument..capturecapture(()),,MatchersMatchers..anyStringanyString(())));;
E X A M P L E S P Y
alexsotoblordofthejars
testCompiletestCompile(('org.powermock:powermock-module-junit4:1.6.4''org.powermock:powermock-module-junit4:1.6.4'))
testCompiletestCompile(('org.powermock:powermock-api-mockito:1.6.4''org.powermock:powermock-api-mockito:1.6.4'))
D E P E N D E N C I E S
alexsotoblordofthejars
@@RunWithRunWith((PowerMockRunnerPowerMockRunner..classclass))
@@PrepareForTestPrepareForTest((StaticClassStaticClass..classclass))
publicpublicclassclassMyTestMyTest{{
}}
P R E P A R E F O R M O C K I N G
alexsotoblordofthejars
PowerMockitoPowerMockito..mockStaticmockStatic((StaticClassStaticClass..classclass));;
MockitoMockito..whenwhen((StaticClassStaticClass..getValuegetValue(())))..thenReturnthenReturn(("Hello""Hello"));;
SystemSystem..outout..printlnprintln((StaticClassStaticClass..getValuegetValue(())));;
PowerMockitoPowerMockito..verifyStaticverifyStatic(());;
M O C K S T A T I C
alexsotoblordofthejars
PowerMockitoPowerMockito..whenNewwhenNew((MyClassMyClass..classclass))
..withNoArgumentswithNoArguments(())
..thenThrowthenThrow((newnewIOExceptionIOException(("errormessage""errormessage"))));;
XxXx==newnewXX(());;
xx..createMyClasscreateMyClass(());;
PowerMockitoPowerMockito..verifyNewverifyNew((MyClassMyClass..classclass))..withNoArgumentswithNoArguments(());;
M O C K C O N S T R U C T O R
alexsotoblordofthejars
CalculatorcalculatorCalculatorcalculator==PowerMockitoPowerMockito..spyspy((newnewCalculatorCalculator(())));;
PowerMockitoPowerMockito..doReturndoReturn((truetrue))..whenwhen((calculatorcalculator,,"isCalculated""isCalculated"));;
SystemSystem..outout..printlnprintln((calculatorcalculator..calculatecalculate(())));;
PowerMockitoPowerMockito..verifyPrivateverifyPrivate((calculatorcalculator))..invokeinvoke(("isCalculated""isCalculated"));;
P R I V A T E M E T H O D
alexsotoblordofthejars
AllthatGlittersisnotGold
B E A W A R E
alexsotoblordofthejars
ifif((SystemSystem..currentTimeMilliscurrentTimeMillis(())>>pojopojo..getStartDategetStartDate(())++expirationexpiration)){{
}}
E X A M P L E O F S Y S T E M
alexsotoblordofthejars
javajava..timetime..ClockclockClockclock;;
publicpublicvoidvoidXX(()){{
ifif((eventDateeventDate..isBeforeisBefore((LocalDateLocalDate..nownow((clockclock)))){{
}}
}}
J A V A 8
alexsotoblordofthejars
TimeResolutionclockTimeResolutionclock;;
publicpublicvoidvoidXX(()){{
ifif((clockclock..nownow(())>>pojopojo..getStartDategetStartDate(())++expirationexpiration)){{
}}
}}
J A V A
alexsotoblordofthejars
S T U B S
alexsotoblordofthejars
S T U B SCannedanswerstocalls
alexsotoblordofthejars
S T U B SCannedanswerstocalls
StateVerification
alexsotoblordofthejars
publicpublicclassclassEmailServiceStubEmailServiceStubimplementsimplementsEmailServiceEmailService{{
privateprivateListemailsListemails==newnewArrayListArrayList<<>>(());;
publicpublicvoidvoidsendMessagesendMessage((StringsubjectStringsubject,,StringbodyStringbody)){{
thisthis..emailsemails..addadd((newnewEmailEmail((subjectsubject,,bodybody))));;
}}
publicpublicStringStringreceiveBodyMessagesWithSubjectreceiveBodyMessagesWithSubject((StringsubjectStringsubject)){{
//...//...
}}
}}
E M A I L S E R V I C E
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
Easytowrite
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
EasytowriteVersatile
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
EasytowriteVersatile
ReimplementingBusiness
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
EasytowriteVersatile
ReimplementingBusinessLogicisoutsidetest
alexsotoblordofthejars
T H E G O O D A N D T H E B A DFast
EasytowriteVersatile
ReimplementingBusinessLogicisoutsidetest
State
alexsotoblordofthejars
alexsotoblordofthejars
@Rule@Rule
publicpublicWireMockRulewireMockRuleWireMockRulewireMockRule==newnewWireMockRuleWireMockRule((80898089));;
stubForstubFor((getget((urlEqualTourlEqualTo(("/planets/""/planets/"))))
..willReturnwillReturn((aResponseaResponse(())
..withHeaderwithHeader(("Content-Type""Content-Type",,"application/json""application/json"))
..withBodywithBody((FilesFiles..readAllBytesreadAllBytes((configFileconfigFile..toPathtoPath(())))))))
));;
clientclient..targettarget(("http://localhost:8089/""http://localhost:8089/"))..pathpath(("planets/""planets/"));;
W I R E M O C K
alexsotoblordofthejars
F A K E S
alexsotoblordofthejars
F A K E SWorkingimplementations
alexsotoblordofthejars
F A K E SWorkingimplementations
Withshortcuts
alexsotoblordofthejars
alexsotoblordofthejars
alexsotoblordofthejars
alexsotoblordofthejars
T H E G O O D A N D T H E B A DAlmostreal
alexsotoblordofthejars
T H E G O O D A N D T H E B A DAlmostrealTestfullstack
alexsotoblordofthejars
T H E G O O D A N D T H E B A DAlmostrealTestfullstack
Slow
alexsotoblordofthejars
T H E G O O D A N D T H E B A DAlmostrealTestfullstack
SlowLearnNewTech
alexsotoblordofthejars
T H E G O O D A N D T H E B A DAlmostrealTestfullstack
SlowLearnNewTech
DifferentBehaviour
alexsotoblordofthejars
M O C K I N G 2 . 0
alexsotoblordofthejars
alexsotoblordofthejars
testCompiletestCompile(('org.jboss.byteman:byteman-bmunit:3.0.3''org.jboss.byteman:byteman-bmunit:3.0.3')){{
excludegroupexcludegroup::'org.testng''org.testng'
}}
B Y T E M A N
alexsotoblordofthejars
publicpublicWebWriterWebWriter((StringfilenameStringfilename)){{
thisthis..filenamefilename==filenamefilename;;
}}
publicpublicPrintStreamPrintStreamopenFileopenFile(()){{
FilefileFilefile==newnewFileFile((filenamefilename));;
trytry{{
FileOutputStreamfosFileOutputStreamfos==newnewFileOutputStreamFileOutputStream((filefile));;
PrintStreampsPrintStreamps==newnewPrintStreamPrintStream((fosfos,,truetrue));;
returnreturnpsps;;
}}catchcatch((FileNotFoundExceptionFileNotFoundExceptionee)){{
SystemSystem..outout..printlnprintln(("Unabletoopenfile""Unabletoopenfile"++filefile..getNamegetName(())));;
SystemSystem..outout..printlnprintln((ee));;
returnreturnnullnull;;
}}
}}
B Y T E M A N
alexsotoblordofthejars
@@RunWithRunWith((orgorg..jbossjboss..bytemanbyteman..contribcontrib..bmunitbmunit..BMUnitRunnerBMUnitRunner..classclass))
publicpublicclassclassTestTest{{
@Test@Test
@@BMRuleBMRule((namename=="handlefilenotfound""handlefilenotfound",,
targetClasstargetClass=="java.io.FileOutputStream""java.io.FileOutputStream",,
targetMethodtargetMethod=="(File)""(File)",,
actionaction=="thrownewFileNotFoundException(\"HahaBytemanfooledyouagain!\")""thrownewFileNotFoundException(\"HahaBytemanfooledyouagain!\")"
))
publicpublicvoidvoidhandleFileNotFoundhandleFileNotFound(())throwsFileNotFoundExceptionthrowsFileNotFoundException{{
SystemSystem..outout..printlnprintln(("--------handleFileNotFound---------""--------handleFileNotFound---------"));;
WebWriterwriterWebWriterwriter==newnewWebWriterWebWriter(("foo.html""foo.html",,"Andrew""Andrew"));;
PrintStreampsPrintStreamps==writerwriter..openFileopenFile(());;
AssertAssert..assertTrueassertTrue((psps====nullnull));;
SystemSystem..outout..printlnprintln(("--------handleFileNotFound---------\n""--------handleFileNotFound---------\n"));;
}}
}}
B Y T E M A N
alexsotoblordofthejars
D O C K E R A S T E S T I N G T O O L
alexsotoblordofthejars
alexsotoblordofthejars
PipelinePlugin
C O N T I N U O U SI N T E G R A T I O N A S C O D E
alexsotoblordofthejars
alexsotoblordofthejars
stagestage'compileAndUnit''compileAndUnit'
nodenode{{
gitbranchgitbranch::'master''master',,urlurl::'https://github.com/lordofthejars/starwars.git''https://github.com/lordofthejars/starwars.git'
gradlegradle'cleantest''cleantest'
stashexcludesstashexcludes::'build/''build/',,includesincludes::'**''**',,namename::'source''source'
stashincludesstashincludes::'build'build//jacocojacoco/*.exec',name:'unitCodeCoverage'/*.exec',name:'unitCodeCoverage'
step([$class:'JUnitResultArchiver',testResults:'**/step([$class:'JUnitResultArchiver',testResults:'**/buildbuild//testtest--resultsresults//**..xml'xml']]))
}}
stagestage'codeQuality''codeQuality'
parallelparallel'pmd''pmd'::{{
nodenode{{
unstashunstash'source''source'
gradlegradle'pmdMain''pmdMain'
stepstep(([[$$classclass::'PmdPublisher''PmdPublisher',,patternpattern::'build/reports/pmd/*.xml''build/reports/pmd/*.xml']]))
}}
}},,'jacoco''jacoco'::{{
nodenode{{
unstashunstash'source''source'
unstashunstash'unitCodeCoverage''unitCodeCoverage'
gradlegradle'jacocoTestReport''jacocoTestReport'
}}
}}
J E N K I N S F I L E ( 1 / 2 )
alexsotoblordofthejars
stagestage'assemble-binaries''assemble-binaries'
nodenode(('linux''linux')){{
unstashunstash'source''source'
withEnvwithEnv(([["SOURCE_BUILD_NUMBER=${env.BUILD_NUMBER}""SOURCE_BUILD_NUMBER=${env.BUILD_NUMBER}"]])){{
gradlegradle'assemble''assemble'
}}
}}
inputmessageinputmessage::"DeployApplicationtoQA?""DeployApplicationtoQA?"
stagenamestagename::'DeploytoQA''DeploytoQA',,concurrencyconcurrency::11
nodenode{{
echoecho"ApplicationDeployedtoQA.""ApplicationDeployedtoQA."
}}
J E N K I N S F I L E ( 2 / 2 )
alexsotoblordofthejars
alexsotoblordofthejars
L E T ' S W I N D D OW N
alexsotoblordofthejars
W H A T Y O U H A V E S E E NUnittestsshouldbeFIRST
alexsotoblordofthejars
W H A T Y O U H A V E S E E NUnittestsshouldbeFIRSTMock,StubsandFakes
alexsotoblordofthejars
W H A T Y O U H A V E S E E NUnittestsshouldbeFIRSTMock,StubsandFakes
PowerMockasDesignWarning
alexsotoblordofthejars
W H A T Y O U H A V E S E E NUnittestsshouldbeFIRSTMock,StubsandFakes
PowerMockasDesignWarningDockerasTestingTool
alexsotoblordofthejars
W H A T Y O U H A V E S E E NUnittestsshouldbeFIRSTMock,StubsandFakes
PowerMockasDesignWarningDockerasTestingTool
Jenkinsisnotstaticanymore
alexsotoblordofthejars
alexsotoblordofthejars
Q U E S T I O N S
alexsotoblordofthejars
http://lordofthejars.github.io/mock-stub-fake/
asotobu@gmail.com
alexsotoblordofthejars
H T T P S : / / G I T H U B . C O M / L O R D O F T H E J A R S / S T A RWA R S
H T T P : / / S I T E . M O C K I T O . O R G /
H T T P S : / / G I T H U B . C O M / J A Y WA Y / P OW E R M O C K
H T T P : / / W I R E M O C K . O R G /
H T T P : / / A R Q U I L L I A N . O R G /
H T T P : / / B Y T E M A N . J B O S S . O R G /
H T T P S : / / G I T H U B . C O M / J E N K I N S C I / WO R K F L OW - P L U G I N