Mock Objects from Concept to Code

885 views

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
885
On SlideShare
0
From Embeds
0
Number of Embeds
13
Actions
Shares
0
Downloads
15
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • Agile has dirty little secret: Iteratively slower and slower…
  • Comprehensive suite of repeatable (automated) regression tests eases the Agilist’s Dilemma…
  • What else? <before advancing>
  • What do these have in common…?
  • Most teams find it challenging to keep them fast and deterministic over time.
  •  Hand-crafted mocks:+ In C++, in/out parameters perhaps easier to handle.
  • Thank you!
  • Mock Objects from Concept to Code

    1. 1. Mock Objects: From Concept to Code Rob Myers for Agile Development Practices East 07 Nov 20127 November 2012 © Agile Institute 2012 1
    2. 2. 7 November 2012 © Agile Institute 2012 2
    3. 3. difficult to set upA database.A complex object graph. Stock Fund Account Stock Stock Investor Stock Account Fund Stock Stock7 November 2012 © Agile Institute 2012 3
    4. 4. expensive to test against*The production database.Your personal credit card.A “password changed” confirmation sent to the CEO of a large investment firm. * Each of these “Career-Limiting Moves” was actually witnessed by me during the “dot-COM” era.7 November 2012 © Agile Institute 2012 4
    5. 5. chaotic The database. A randomizer. The weather.7 November 2012 © Agile Institute 2012 5
    6. 6. …slow…The database.The network.The filesystem.Interplanetary radio signals?!7 November 2012 © Agile Institute 2012 6
    7. 7. Fast! Reliable!7 November 2012 © Agile Institute 2012 7
    8. 8. 7 November 2012 © Agile Institute 2012 8
    9. 9. from Martin Fowler et al• Fakes provide reasonable facsimiles of the real thing, but are not quite robust enough for production (e.g., an in-memory database).• Stubs provide scripted responses to calls. They may also record information about calls made during the test.• Mocks are programmed by tests, creating expectations for potentially the entire specification of a call, including arguments.7 November 2012 © Agile Institute 2012 9
    10. 10. classicists v. mockistsHand-Crafted Mocks (“Stubs”) + Simple & familiar. + Black-box. + Can do something clever (e.g., throw exception for a special argument), or hold state (e.g., collect a buffered result for an assertion). - Can get too complex if reused everywhere.Dynamic Mocking Tools (“Mocks”) + Great for interactions/protocols. + Can be used in numerous variations or scenarios. - White-box: Can be too explicit about implementation.7 November 2012 © Agile Institute 2012 10
    11. 11. never an absolutist7 November 2012 © Agile Institute 2012 11
    12. 12. Investments Earthbound7 November 2012 © Agile Institute 2012 12
    13. 13. Write StockQuote classCreate a StockQuote for the current price of a LunEx stock.Quote total should reflect our 2% commission on all LunEx transactions, plus the flat LunEx communication surcharge of $10.Be sure we invoke LunEx once per quote, as they charge $0.05 per invocation! 7 November 2012 © Agile Institute 2012 13
    14. 14. DATABASE StockQuote LunExServices+ double total() + double currentPrice( String symbol )7 November 2012 © Agile Institute 2012 14
    15. 15. Testing with a Mock StockQuote LunExServices + double total() + double currentPrice( String symbol ) MockLunExServices StockQuoteTests + double currentPrice(+ totalWorksRight() String symbol defines ) 7 November 2012 © Agile Institute 2012 15
    16. 16. Write StockQuote classCreate a StockQuote for the current price of a LunEx stock.Quote total should reflect our 2% commission on all LunEx transactions, plus the flat LunEx communication surcharge of $10.Be sure we invoke LunEx once per quote, as they charge $0.05 per invocation! 7 November 2012 © Agile Institute 2012 16
    17. 17. a test@Testpublic void totalCalculatesCorrectly() { // given LunExServices myService = Mockito.mock(LunExServices.class); Mockito.when(myService.currentPrice("HE3")) .thenReturn(12.00); StockQuote quote = new StockQuote("HE3", 100, myService); // when double total = quote.total(); // then Assert.assertEquals(1234.00, total, 0.00001);}7 November 2012 © Agile Institute 2012 17
    18. 18. just enough to compile & failpackage earthboundInvestments;import lunEx.LunExServices;public class StockQuote { public StockQuote(String symbol, int numberOfShares, LunExServices service) { } public double total() { return 0; }}7 November 2012 © Agile Institute 2012 18
    19. 19. 7 November 2012 © Agile Institute 2012 19
    20. 20. “Obvious Implementation”public class StockQuote { private final double total; public StockQuote(String symbol, int numberOfShares, LunExServices service) { total = service.currentPrice(symbol) * numberOfShares * 1.02 + 10.00; } public double total() { return total; }}7 November 2012 © Agile Institute 2012 20
    21. 21. 7 November 2012 © Agile Institute 2012 21
    22. 22. what else?@Testpublic void totalCalculatesCorrectly() { // given LunExServices myService = Mockito.mock(LunExServices.class); Mockito.when(myService.currentPrice("HE3")) .thenReturn(12.00); StockQuote quote = new StockQuote("HE3", 100, myService); // when double total = quote.total(); // then Assert.assertEquals(1234.00, total, 0.00001); Mockito.verify(myService, Mockito.times(1)) .currentPrice("HE3");}7 November 2012 © Agile Institute 2012 22
    23. 23. test using hand-crafted mock@Testpublic void totalCalculatesCorrectly_usingHandCraftedMock() { // given MockLunExServices myService = new MockLunExServices(12.00); StockQuote quote = new StockQuote("HE3", 100, myService); // when double total = quote.total(); // then Assert.assertEquals(1234.00, total, 0.00001); Assert.assertTrue(myService.wasCalledOnceAndOnlyOnce());}7 November 2012 © Agile Institute 2012 23
    24. 24. hand-crafted mock public class MockLunExServices extends LunExServices { private double valueToReturn; private int callCount = 0; public MockLunExServices(double valueToReturn) { this.valueToReturn = valueToReturn; } @Override public double currentPrice(String symbol) { callCount++; return valueToReturn; } public boolean wasCalledOnceAndOnlyOnce() { return callCount == 1; } }7 November 2012 © Agile Institute 2012 24
    25. 25. Summary: 1. Agile: Good! 2. “Agilist’s Dilemma”: Very bad. 3. TDD: Great! 4. Slow, non-deterministic tests: Bad. 5. Mocks: Good. 6. “Never an Absolutist!”7 November 2012 © Agile Institute 2012 25
    26. 26. 7 November 2012 © Agile Institute 2012 26
    27. 27. Rob.Myers@agileInstitute.com http://PowersOfTwo.agileInstitute.com/ @agilecoach7 November 2012 © Agile Institute 2012 27

    ×