Your SlideShare is downloading. ×
0
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Test Driven Development Primer LJC Open Conference
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Test Driven Development Primer LJC Open Conference

3,455

Published on

Sometimes getting started with Test Driven Development is a difficult change for people to pick up. This presentation gives a brief guide to how to get started and suggests a few examples and …

Sometimes getting started with Test Driven Development is a difficult change for people to pick up. This presentation gives a brief guide to how to get started and suggests a few examples and practical points. The examples are a bit heavy in terms of they include some Spring - something I'll be looking to improve in the future

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
3,455
On Slideshare
0
From Embeds
0
Number of Embeds
68
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Test Driven Development Primer ! Jim Gough ! twitter: @JavaJimLondon email: jpgough@gmail.com aptood: http:/ /aptood.com/6f1a22
  • 2. Schedule Introduction Cognitive implications Mocking Legacy code
  • 3. Who am I? 6 years developing in finance. London Java Community/JCP Panel. Strong belief in craftsmanship.
  • 4. Disclaimer Based on personal experience. Based on what others found difficult. I probably take some shortcuts. I can definitely improve.
  • 5. What is Test Driven Development? Write a test first. Make sure it compiles, runs and fails. Write the simplest code to pass the test. Refactor the code and if necessary the test.
  • 6. http://www.flickr.com/photos/nocallerid_man/3638360458/
  • 7. Cognitive Implications http://www.flickr.com/photos/aloha75/4571410233
  • 8. Cognitive Implications http://www.flickr.com/photos/eepaul/3946701733/
  • 9. Cognitive Implications Compose. Comprehend. Vary depending on maintenance vs new development. Rapid increase in complexity from the offset.
  • 10. Jigsaws
  • 11. Get the tech right
  • 12. One Approach Controller/ UI End Point Order Controller Handler Logic Bartender Mock External Dependencies Database Mock
  • 13. Difficult Change Reverse the way the way that you think. Start from the interactions and the spec. Asking questions. Exploring the domain. Answer the question with solutions. Take a step further in.
  • 14. Mocking Ensure we only test one unit of code at a time. ! ! Helps us keep our goal of thinking about each part in stages. http:/ /www.flickr.com/photos/ick9s/3950547398/
  • 15. Verifying Interaction @RunWith(MockitoJUnitRunner.class) public class TestOrderController { @Mock private BartenderService bartender; private OrderController orderController; @Before public void before() { orderController = new OrderController(); orderController. setOrderService(bartender);
  • 16. Verifying Interaction @Test public void testOrderBeer() { orderController.order(Drink.BEER); verify(bartender).obtain(Drink.BEER); ! }
  • 17. Verifying Interaction @Test public void testOrderTwoDrinks() { Drink[] drinks = new Drink[] { Drink.BEER, Drink.WINE }; ! orderController.order(drinks); verify(bartender, times(2)) .obtain(any(Drink.class)); ! }
  • 18. Verifying Interaction @Test public void testOrderTwoDrinks() { Drink[] drinks = new Drink[] { Drink.BEER, Drink.WINE }; ! orderController.order(drinks); verify(bartender).obtain(Drink.BEER); verify(bartender).obtain(Drink.WINE); verifyNoMoreInteractions(bartender); ! }
  • 19. Stubbing when(databaseBean.inStock(Drink.BEER)) .thenReturn(true); when(databaseBean.inStock(Drink.BEER)) .thenReturn(true) .thenReturn(false); when(databaseBean.inStock(any(Drink.class)) .thenReturn(true) .thenReturn(false);
  • 20. Stubbing doThrow(new RuntimeException()).when(databaseBean).remov eStock(); when(namedParameterJdbcTemplate.update(eq( Employer.INSERT_EMPLOYER), any(SqlParameterSource.class), any(GeneratedKeyHolder.class), any(String[].class))).then(new Answer<Integer>() { ! @Override public Integer answer(InvocationOnMock invocation) throws Throwable { //Do things with arguments // Return } });
  • 21. Customer wants to order an ale.
  • 22. private AnnotationMethodHandlerAdapter handlerAdapter; protected MockHttpServletResponse response; @Test public void customer_orders_an_ale() { //Initialise handlerAdapter MockHttpServletRequest request = new MockHttpServletRequest(); request.setURI(“/order/ale”); request.setMethod(RequestMethod.POST); Ale ale = new Ale(“IPA”); request.setContent(mapper.writeValueAsBytes( ale)); handlerAdapter.handle(request, response, orderController); verify(bartender).orderAle(ale);
  • 23. private Bartender bartender; @RequestMapping(value="order/ale", method=RequestMethod.POST) @RequestBody @ResponseStatus(value=HttpStatus.OK) public Drink orderAle(@RequestBody Ale ale) { return bartender.order(ale); ! ! ! }
  • 24. @Test public void pour_ale_that_is_available() {} @Test public void ale_not_available() {}
  • 25. @Mock private JdbcTemplate jdbcTemplate; @InjectMocks private Bartender bartender; @Test public void pour_ale_that_is_available() { Object[] params = new Object[1]; params[0] = “IPA”; when(jdbcTemplate.query(“SELECT * FROM Stock WHERE NAME = ?”, params, any(BeerMapper.class)).thenReturn(new Drink(“IPA”)); Drink drink = bartender.order(ale); verify(jdbcTemplate).query(anyString(), any(Object[].class), any(BeerMapper.class)); verify(jdbcTemplate).update(REMOVE_DRINK, params); assertThat(drink.getName(), isEqualTo(“IPA”));
  • 26. @Mock private JdbcTemplate jdbcTemplate; @InjectMocks private Bartender bartender; @Test public void ale_not_available() { when(jdbcTemplate.query(“SELECT * FROM Stock WHERE NAME = ?”, any(Object[].class), any(BeerMapper.class)) .thenReturn(null); Drink drink = bartender.order(ale); verify(jdbcTemplate).query(anyString(), any(Object[].class), any(BeerMapper.class)); assertNull(drink);
  • 27. private JdbcTemplate jdbcTemplate; public Drink order(Ale ale) { Object[] params = new Object[] { ale.getName() }; List<Drink> drinks = jdbcTemplate.query(SELECT_DRINK, params, beerMapper); if(drinks.size() > 0) { jdbcTemplate.update(REMOVE_DRINK, params); return drinks.get(0); } else { return null; }
  • 28. Refactoring Legacy Code
  • 29. Legacy Code Often following push and pray mentality. Lots of regression or hands on testing. Developer time is often wasted. Highly coupled code, changes become risker over time. Team culture can be of a fixed way.
  • 30. Can I Use TDD? Absolutely, but there are a few new techniques to learn. Don’t change production code without a test.
  • 31. One Approach Write tests to cover production code. Only refactor allowed are automated IDE steps. Break statics using intermediate step by identifying seams.
  • 32. Dealing with Seams public class MyLegacyClass { public String getTimesLoggedIn() { User user = UserSession.getInstance() .getLoggedInUser(); return user.timesLoggedIn(); } }
  • 33. Dealing with Seams public class MyLegacyClass { public String getTimesLoggedIn() { User user = UserSession.getInstance() .getLoggedInUser(); return user.timesLoggedIn(); } protected User getLoggedInUser() { return UserSession.getInstance() .getLoggedInUser(); !
  • 34. Dealing with Seams public class MyLegacyClass { public String getTimesLoggedIn() { User user = getLoggedInUser(); return user.timesLoggedIn(); } protected User getLoggedInUser() { return UserSession.getInstance() .getLoggedInUser(); !
  • 35. Dealing with Seams public class MyLegacyClassTest { private User loggedInUser; private class TestableMyLegacyClass extends MyLegacyClass { @Override protected User getLoggedInUser() { ! return loggedInUser; ! ! ! } ! }
  • 36. Recommended Tutorial http:/ /www.youtube.com/watch?v=_NnElPO5BU0
  • 37. Benefits Explore the domain, comprehend the problem. Start with meaningful requirements. Framework to solve complicated problems. High confidence in changes. Eventually, quicker more productive and accurate. Sanity.
  • 38. Challenges Initially you have to reverse way of thinking. You sometimes have to sell it to team members. Sell the benefits to management. Less risk changes: One project, 5-6 issues per week - now 5 issues per year. Developer productivity goes up.
  • 39. The End Get ready to test! ! Jim Gough ! twitter: @JavaJimLondon email: jpgough@gmail.com aptood: http:/ /aptood.com/6f1a22

×