Upload
ortus-solutions-corp
View
125
Download
5
Embed Size (px)
DESCRIPTION
Mock what? What Mock?Learn What is Mocking, and how to use Mocking with ColdFusion testing, development, and continuous integration. Look at Mocking and Stubbing with a touch of Theory and a lot of Examples, including what you could test, and what you should test… and what you shouldn't test (but might be fun).
Citation preview
Just Mock It Mocks and Stubs
Presented by Gavin Pickin Slides: http://gpickin.com/itb2014/ Website: http://gpickin.com Twitter: @gpickin
Introduc)on
• Follow along with resources from h6p://gpickin.com/itb2014/
• If you want to find out more about me, my website has more than enough informa)on
20 Second Agenda
• Unit Tes)ng -‐ Recap • What is Mocking • What is a Mock / Stub • Why Mock • Let’s look at some Mocking
Unit Tes)ng
“unit tes)ng is a soOware verifica)on and valida)on method in which a programmer tests if individual units of source code are fit for use. A unit is the smallest testable part of an applica)on” -‐ wikipedia
Unit Tes)ng
• Can improve code quality -‐> quick error discovery
• Code confidence via immediate verifica)on • Can expose high coupling • Will encourage refactoring to produce > testable code
• Remember: Tes)ng is all about behavior and expecta)ons
Bugs Hurt
Bugs Hurt
• Bugs hurt – the later in the process, the harder to fix.
• Test Early and OOen – Find them before they rot your founda)on
• Testable Code is Maintainable Code
Unit Tes)ng Basics
Test Driven Development
Important Tests
• Unit Tes)ng – Test behavior of individual objects
• Integra)on Tes)ng – Test En)re Applica)on from Top Down
• UI verifica)on tes)ng – Verifica)on via HTML/Visual elements
Important Tes)ng Tools
• TestBox (Run BDD and MXUnit style) • IDE -‐ CF Builder / Eclipse • Mocking Framework • ANT • Jenkins, Bamboo, Teamcity, other Cis • Selenium • Jmeter or Webstress Tool, Apache AB
What is Mocking?
According to Merriam Webster • to laugh at or make fun of (someone or something) especially by copying an ac)on or a way of behaving or speaking
• to imitate (as a mannerism) closely
What is Mocking?
"A mock object is an object that takes the place of a ‘real’ object in such a way that makes tes)ng easier and more meaningful, or in some cases, possible at all" by Sco6 Bain -‐ Emergent Design
Mocks
Mocks
Mocks
Mocks
Stub Object
• A stub is an empty container, that represents an Object.
• This can be useful for represen)ng CFCs and Objects that haven’t been wri6en yet.
Why use Mocking
• Isolate your SUT -‐> SoOware Under Test • To build against interfaces & contracts • Building against missing integra)on pieces • To control data and expecta)ons • Mock components whose behavior is undesirable or hard to control
Why Mock?
• How do you test when helper components that are not built yet?
• How do you do controlled excep)ons? • How do you test & control external API calls? • How do you control results from ColdFusion tags or func)ons?
• How do you control network connec)ons? Do you pull the network plug?
Why Mock?
How do you test code like this? <cfdirectory ac)on=”list” directory=”#arguments.path#” name=”qResults”> <ck6p url=”#arguments.urlPath#” results=”qResults”> <cfmail to=”#to#” from=”#from#” subject=”#subject#”>#content#</cfmail> <cfquery /> func)on init(){ var helper = new Helper(); } private func)on getData(){ return data; }
The COLD hard truth – It can Hurt
• Tes)ng some code is hard, or almost impossible.
• Refactor it • Mock it • Test It • With CI, you can forget about it
Un)l it breaks
Refactor to make it Mockable
• Original: <cfdirectory ac)on=”list” directory=”/myapp/path” name=”qResults”>
• Refactored <cffunc)on name=”getFiles” output=”false” returnType=”query”> <cfargument name=”path”> <cfset var qResults = “”> <cfdirectory ac)on=”list” directory=”#arguments.path#” name=”qResults”> ... Process Here ... <cfreturn qResults> </cffunc)on>
Normal View of your Service
Mock/Test View of your Service
What do we Mock?
• Excep)ons • Data • CFC and Objects • Methods in our CFCs • Proper)es in our CFCs
Mocking Framework
• Introducing
What can MockBox do?
• Mock Objects with or without implementa)ons • Mock methods & proper)es in any scope • Create Stub Objects -‐> Non-‐existent objects • Mock excep)ons • Mock arguments to results • Logging & Debugging • Verifica)on methods • State Machine Results
Sepng up MockBox
• Standalone Version (FW/1, Fusebox, Model Glue, Home Brewed) mockBox = createObject(“component”,”mockBox.system.tes)ng.MockBox”).init();
• Running from inside ColdBox (outside of TestBox) mockBox = createObject(“component”,”coldbox.system.tes)ng.MockBox”).init();
Using MockBox
• MockBox does its magic dynamically, adding / decora)ng CFCs with necessary methods.
• CreateMock() user = mockBox.createMock(“model.User”);
• CreateEmptyMock() dao = mockBox.createEmptyMock(“model.UserDAO”);
• PrepareMock() mockBox.prepareMock( service );
Using MockBox -‐ Stubs
• CreateStub() – Create a simple empty Stub – Pass an Implements to get a Mock Interface – Pass an Extends to get a Mock with Inheritance
nonExistentService = mockBox.createStub(); mockInterface = mockBox.createStub(implements=”model.ICache”); mockInheritance = mockbox.createStub(extends=”model.SecurityService”);
Injected Methods
$()
• Argument – method – returns – preserveReturnType – throwExcep)on – throwType – throwDetail – throwMessage – callLogging
// Cascaded mocks mockUser.$(“isFound”,true).$(“isDirty”,true); // Mock Exception mockUser. $(method=”save”, throwsException=true, throwType=”IllegalStateException”, throwMessage=”Invalid User Data”); // Mock Return Objects mockRole = mockBox.createMock(“Role”); service.$(method=”getRole”,returns=mockRole);
Using $()
mockUser = mockBox.createEmptyMock(“model.User”).init(); userService = mockBox.createMock(“model.UserService”).init(); user = userService.$(“get”, mockUser); //Technique 1 – Constant Result user.$(“getName”, “Rose Tyler”); //Technique 2 – Rota)ng Results user.$(“getName”).$results(“Rose Tyler”, “Amelia Pond”, “River Song”);
Using $args()
• Results based on the Arguments Passed • Must be chained via Results. // Call to Mock if( dao.getSepng(“userAudit”) ){ startAudit( dao.getSepng(“auditTables”) ); }; // Mocking Calls dao.$(“getSepng”).$args(“userAudit”).$results(true); dao.$(“getSepng”).$args(“auditTables”).$results(“user,order,
Using $args()
• Arguments are smart like normal func)ons – Posi)onal Arguments
saveUser(”Rose”,”Tyler”);
– Named Arguments saveUser(fname=”Rose”,lname=”Tyler”);
– Argument Collec)ons data = { fname = “Rose”, lname = “Tyler” };
saveUser(argumentCollec)on=data);
$results()
• Your results can be – Constant – Or Sequenced
• Your results will loop over and over.
• Argument Based Results can also be repe))ve in a sequence.
$property()
• Mock any property on any scope • Great for sepngs and dependency injec)on mocking // Mock a sepng on the variables scope service.$property(“cacheAc)ve”,”variables”,true); // Mock a file u)lity object mockU)l = mockbox.createEmptyMock(“u)l.FileU)ls”); service.$property(“fileU)l”,”variables”, mockU)l); // Mock in the variables.instance scope path service.$property(“isDirty”,”instance”,true);
Verifica)on Methods * Verification methods return boolean so they can be asserted
Verifica)on Methods func)on testVerifyCallCount(){
test.$("displayData",queryNew('')); assertTrue( test.$never() ); assertTrue( test.$never(“displayData”) ); test.displayData(); assertFalse( test.$)mes(1,”displayData”) ); assertFalse( test.$once(”displayData”) ); test.displayData(); assertEquals(true, test.$verifyCallCount(2));
}
Verifica)on Methods func)on testMockMethodCallCount(){
test.$("displayData",queryNew('')); test.$("getLuis",1); assertEquals(0, test.$count("displayData") ); assertEquals(-‐1, test.$count("displayData2") );
}
Lets look at a Demo
h6p://justmockit.local.com Code available at: h6ps://github.com/gpickin/justmockitdemo
The End – Thank you
• Thanks everyone for making it this far • All of the materials will be on my ITB presenta)on Site: h6p://www.gpickin.com/itb2014/
• Hit me up on twi6er @gpickin • Read more on my blog: h6p://gpickin.com • Check out my CFO Session Thursday, 15th 11:30am – 12:30am on Lakes Ballroom C