Xp Day 080506 Unit Tests And Mocks


Published on

Introduction to Mocks in Unit Tests

Published in: Technology, Education
  • Be the first to comment

  • Be the first to like this

No Downloads
Total Views
On Slideshare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Xp Day 080506 Unit Tests And Mocks

    1. 1. Unit Tests and Mocks libraries Guillaume Carre May 2008 XP Day Paris Certified ScrumMaster
    2. 2. Agenda <ul><li>Introduction </li></ul><ul><li>Mocks </li></ul><ul><ul><li>Unit Testing and Mock objects </li></ul></ul><ul><ul><li>Automatic generation of mock objets: EasyMock code examples </li></ul></ul><ul><li>Mocks libraries comparison </li></ul><ul><li>Mocks and Test Driven Development </li></ul><ul><li>Conclusion </li></ul><ul><li>Links </li></ul><ul><li>Questions </li></ul>
    3. 3. Introduction <ul><li>Writing defect-free software is exceedingly difficult </li></ul><ul><li>Automated verification of software behavior is one of the biggest advances in development methods in the last few decades </li></ul><ul><li>The sooner we get feedback, the more quickly we can react </li></ul><ul><li>Tests can help understand the “System Under Test “ (SUT) </li></ul><ul><li>Without unit tests, we can’t refactor code </li></ul><ul><li>Unit tests are the backbone of Agile Methodologies </li></ul>
    4. 4. Unit Tests / Integration Tests <ul><li>Unit Test: code tested in isolation </li></ul><ul><li>Unit Tests don’t see the big picture, we need to validate that all pieces of code work together </li></ul><ul><li>Of course Integration and Functional Tests are mandatory, even with good Unit Tests </li></ul>
    5. 5. Unit Tests: test code in isolation <ul><li>Definition : a unit test exercises a single class in isolation of all others </li></ul><ul><li>Test one feature at a time: </li></ul><ul><ul><li>We need to know exactly what we are testing </li></ul></ul><ul><ul><li>We need to know exactly where problems are </li></ul></ul><ul><li>Test code must be readable and clear </li></ul><ul><li>To test code in isolation, collaborators are replaced by dummy objects, « stubs » or « mocks » </li></ul>
    6. 6. Unit tests and Mock objects <ul><li>Mocks objects are dummy implementations of collaborators </li></ul><ul><li>Simpler than the real code </li></ul><ul><li>Mocks are not stubs </li></ul><ul><ul><li>Stubs check state </li></ul></ul><ul><ul><li>Mocks check behaviour </li></ul></ul><ul><li>Hand crafted stubs can be to hard to write and to maintain </li></ul>
    7. 7. Benefits from using Mock objects <ul><li>Tests are specification, use of Mock objects helps in having a good description of the SUT behaviour </li></ul><ul><li>Common format for unit tests </li></ul><ul><li>Code ends up simple and clean with a better design </li></ul><ul><li>Tests run faster </li></ul><ul><li>Design for testability </li></ul>
    8. 8. Code example <ul><li>Simple cart and stock application </li></ul><ul><li>CartManager is the System Under Test (SUT) </li></ul><ul><li>ProductDAO is the collaborator of CartManager </li></ul>
    9. 9. Mocks libraries <ul><li>No need to write mocks at all </li></ul><ul><li>Mocks are created dynamically at test run time </li></ul><ul><li>3 phases: </li></ul><ul><ul><li>Mock setup : parameter expectations, return values, call counts, thrown exceptions </li></ul></ul><ul><ul><li>Mock replay to record the behaviour </li></ul></ul><ul><ul><li>Mock verification </li></ul></ul>
    10. 10. Without mock objects
    11. 11. With mock objects (EasyMock)
    12. 12. Usage 1/3 <ul><li>Expect, return and replay </li></ul><ul><li>expect (productDAOMock.isInStock( PRODUCT_ID , 20)) .andReturn( true ); </li></ul><ul><li>replay( productDAOMock ); </li></ul><ul><li>Verify behavior </li></ul><ul><li>verify( productDAOMock ); </li></ul><ul><li>AssertionError is thrown if an expectation has not been described </li></ul><ul><li>java.lang.AssertionError Unexpected method call removeFromStock(1L, 20) </li></ul><ul><li>AssertionError is thrown if an expectation has been described but not fullfilled </li></ul><ul><li>java.lang.AssertionError </li></ul><ul><li>removeFromStock(1L, 20): expected: 1, actual: 0 </li></ul>
    13. 13. Usage 2/3 <ul><li>Explicit number of calls </li></ul><ul><li>If isInStock is called 3 times, instead of </li></ul><ul><li>productDAOMock.isInStock( PRODUCT_ID , 20)) ; </li></ul><ul><li>productDAOMock.isInStock( PRODUCT_ID , 20)) ; </li></ul><ul><li>productDAOMock.isInStock( PRODUCT_ID , 20)) ; </li></ul><ul><li>One can write: </li></ul><ul><li>productDAOMock.isInStock( PRODUCT_ID , 20)) ; </li></ul><ul><li>expectLastCall().times(3); </li></ul><ul><li>Throwing an exception </li></ul><ul><li>expect( productDAOMock.isInStock( PRODUCT_ID , 20) ).andThrow( new ProductDAOException() ); </li></ul>
    14. 14. Usage 3/3 <ul><li>Strict mocks </li></ul><ul><li>-> With strict mocks order of methods calls is checked </li></ul><ul><li>ProductDAO productDAO = createStrictMock (ProductDAO.class); </li></ul><ul><li>Argument matchers </li></ul><ul><li>-> used if mock method parameters are instanciated from inside the tested method </li></ul><ul><li>expect (productDAOMock.isInStock( isA(Long.class) , </li></ul><ul><li>isA(Integer.class))) .andReturn( true ); </li></ul><ul><li>Other argument matchers: isNull(), eq(X value), anyObject(), startsWith(String prefix) , etc… </li></ul>
    15. 15. Mocks libraries roundup <ul><li>JMock 2: </li></ul><ul><ul><li>Refactorable test code </li></ul></ul><ul><ul><li>Promotes the use of anonymous classes: test code is difficult to read </li></ul></ul><ul><li>JMock 1: </li></ul><ul><ul><li>First mock library </li></ul></ul><ul><ul><li>Treat methods as Strings: test code is not refactorable </li></ul></ul><ul><li>EasyMock: </li></ul><ul><ul><li>Best syntax out there: refactorable AND readable </li></ul></ul><ul><ul><li>Used in Spring framework for unit tests </li></ul></ul><ul><li>Mockito: </li></ul><ul><ul><li>The new kid on the block </li></ul></ul><ul><ul><li>&quot;run – verify&quot; pattern (no &quot;record&quot;) </li></ul></ul>
    16. 16. Mocks & TDD <ul><li>Classical TDD: use real objects if possible, and a double if not possible </li></ul><ul><li>Coding manual stubs can take more time than using mocks </li></ul><ul><li>Mockist TDD: will always use a mock for any collaborator </li></ul><ul><li>Classical TDDers code “dummy” collaborators, to make the test green, and then implement collaborators when needed. Using mocks for collaborators can seem awkward for a classical TDDer </li></ul><ul><li>Usually TDDers prefer the Classical approach </li></ul><ul><li>Give the Mockist approach a try, and choose the one you prefer! </li></ul>
    17. 17. Cons <ul><li>Debugging using generated mocks can be more difficult than with hand written mocks </li></ul><ul><li>A risk is to develop too much specified unit tests, hence fragile tests, that will break on each SUT minor modification </li></ul>
    18. 18. Links <ul><li>http://www.mockobjects.com </li></ul><ul><li>http://www.martinfowler.com/articles/mocksArentStubs.html </li></ul><ul><li>http://www.jmock.org </li></ul><ul><li>http://www.easymock.org </li></ul><ul><li>http://code.google.com/p/mockito </li></ul>
    19. 19. Conclusion <ul><li>In our experience, mocks libraries save time, and help in writing simple, consistent and predictable mocks </li></ul><ul><li>Developing with mock objects has beneficial effects on the team members coding style (coding to Interfaces, Dependency Injection, etc.) </li></ul><ul><li>Integration testing and Functional testing are of course still necessary, even with good unit tests </li></ul>
    20. 20. Questions <ul><li>? </li></ul>