Mock geecon2

Embed Size (px)

Citation preview

1. One mock too far @milipski pragmatists.pl 2. public class InvoiceService { private InvoiceDataFactory invoiceDataFactory; private InvoiceRepository invoiceRepository; public Invoices findAll() { InvoiceData invoiceData = invoiceDataFactory.create(); Invoices invoices = invoiceRepository.findAll(invoiceData); return invoices; } } 3. @Test public void should_fetch_from_repository_using_invoice_data_from_factory() { InvoiceDataFactory invoiceDataFactory = mock(InvoiceDataFactory.class); InvoiceData invoiceData = new InvoiceData(); when(invoiceDataFactory.create()).thenReturn(invoiceData); InvoiceRepository invoiceRepository = mock(InvoiceRepository.class); InvoiceService invoiceService = new InvoiceService(invoiceDataFactory, invoiceRepository); invoiceService.findAll(); verify(invoiceDataFactory).create(); verify(invoiceRepository).findAll(invoiceData); } 4. @Test public void should_fetch_from_repository_using_invoice_data_from_factory() { InvoiceDataFactory invoiceDataFactory = mock(InvoiceDataFactory.class); InvoiceData invoiceData = new InvoiceData(); when(invoiceDataFactory.create()).thenReturn(invoiceData); InvoiceRepository invoiceRepository = mock(InvoiceRepository.class); InvoiceService invoiceService = new InvoiceService(invoiceDataFactory, invoiceRepository); invoiceService.findAll(); verify(invoiceDataFactory).create(); verify(invoiceRepository).findAll(invoiceData); } 5. @Test public void should_fetch_from_repository_using_invoice_data_from_factory() { InvoiceDataFactory invoiceDataFactory = mock(InvoiceDataFactory.class); InvoiceData invoiceData = new InvoiceData(); when(invoiceDataFactory.create()).thenReturn(invoiceData); InvoiceRepository invoiceRepository = mock(InvoiceRepository.class); InvoiceService invoiceService = new InvoiceService(invoiceDataFactory, invoiceRepository); invoiceService.findAll(); verify(invoiceDataFactory).create(); verify(invoiceRepository).findAll(invoiceData); } 6. @Test public void should_fetch_from_repository_using_invoice_data_from_factory() { InvoiceDataFactory invoiceDataFactory = mock(InvoiceDataFactory.class); InvoiceData invoiceData = new InvoiceData(); when(invoiceDataFactory.create()).thenReturn(invoiceData); InvoiceRepository invoiceRepository = mock(InvoiceRepository.class); InvoiceService invoiceService = new InvoiceService(invoiceDataFactory, invoiceRepository); invoiceService.findAll(); verify(invoiceDataFactory).create(); verify(invoiceRepository).findAll(invoiceData); } 7. duplication of implementation InvoiceData invoiceData = invoiceDataFactory.create(); Invoices invoices = invoiceRepository.findAll(invoiceData); when(invoiceDataFactory .create()).thenReturn(invoiceData); verify(invoiceRepository).findAll(invoiceData); 8. Bad readability @Test public void should_fetch_from_repository_using_invoice_data_from_factory() { InvoiceDataFactory invoiceDataFactory=mock(InvoiceDataFactory.class); InvoiceData invoiceData = new InvoiceData(); when(invoiceDataFactory.create()).thenReturn(invoiceData); InvoiceRepository invoiceRepository = mock(InvoiceRepository.class); InvoiceService invoiceService = new InvoiceService( invoiceDataFactory, invoiceRepository); invoiceService.findAll(); verify(invoiceDataFactory).create(); verify(invoiceRepository).findAll(invoiceData); } 9. Change-Detector tests fail after ANY change to production code. http://googletesting.blogspot.com/ 10. Mock Objects are not bad but we use them in a bad way 11. public class InvoiceService { private InvoiceDataFactory invoiceDataFactory; private InvoiceRepository invoiceRepository; public Invoices findAll() { InvoiceData invoiceData = invoiceDataFactory.create(); Invoices invoices = invoiceRepository.findAll(invoiceData); return invoices; } } 12. Procedural code gets information then makes decisions ... Alec Sharp 13. Mocks don't get along with procedural code 14. QUERY COMMAND INCOMMING OUTGOING 15. Incoming Query query() 16. Incoming Query query() response 17. public class InvoiceService { private InvoiceDataFactory invoiceDataFactory; private InvoiceRepository invoiceRepository; public Invoices findAll() { InvoiceData invoiceData = invoiceDataFactory.create(); Invoices invoices = invoiceRepository.findAll(invoiceData); return invoices; } } Incoming Query 18. Stubs instead of mocks @Test public void should_fetch_invoices() { InvoiceService invoiceService = new InvoiceService( new InvoiceDataFactoryStub(), new InvoiceRepositoryStub( new Invoice("123"), new Invoice("456"))); Invoices invoices = invoiceService.findAll(); assertThat(invoices).containsOnly(new Invoice("123"), new Invoice("456")); } 19. Asserting on retuned value @Test public void should_fetch_invoices() { InvoiceService invoiceService = new InvoiceService( new InvoiceDataFactoryStub(), new InvoiceRepositoryStub( new Invoice("123"), new Invoice("456"))); Invoices invoices = invoiceService.findAll(); assertThat(invoices).containsOnly(new Invoice("123"), new Invoice("456")); } 20. Mocks assert on messages Stubs return values 21. QUERY COMMAND INCOMMING Assert on result OUTGOING 22. Outgoing Query query() 23. Outgoing Query query() response 24. Outgoing Query public class InvoiceService { private InvoiceDataFactory invoiceDataFactory; private InvoiceRepository invoiceRepository; public Invoices findAll() { InvoiceData invoiceData = invoiceDataFactory.create(); Invoices invoices = invoiceRepository.findAll(invoiceData); return invoices; } } 25. QUERY COMMAND INCOMMING Assert on result OUTGOING Stub, avoid asserting 26. Don't mess mocks with stubs 27. Incoming Command command() 28. Incoming Command command() 29. PrepaidTopup service example press(key) sendRequest() getSelection() PrepaidTopup 30. PrepaidTopup service example press(key) sendRequest() getSelection() PrepaidTopup 31. Incoming Command @Test public void makes_selection_by_pressing_numbers() { PrepaidTopup prepaidTopup = new PrepaidTopupStand(new OrderHandler()); prepaidTopup.press(5); prepaidTopup.press(0); String selection = prepaidTopup.getSelection(); assertThat(selection).isEqualTo("50"); } 32. QUERY COMMAND INCOMMING Assert on result Assert on state change OUTGOING Stub, avoid asserting 33. Outgoing Command command() 34. Procedural code gets information then makes decisions, Object Oriented code tells objects to do things Alec Sharp 35. In OOP behaviour is found in messages 36. PrepaidTopup service press(key) sendRequest() PrepaidTopup placeOrder(selection) OrderHandler 37. public interface PrepaidTopup { public void press(Integer number); public void sendRequest(); } PrepaidTopup service 38. @Test public void sends_request_with_selection() { OrderHandler orderHandler = mock(OrderHandler.class); PrepaidTopup prepaidTopup = new PrepaidTopupStand(orderHandler); prepaidTopup.press(5); prepaidTopup.press(0); prepaidTopup.sendRequest(); verify(orderHandler).placeOrder("50"); } Verify on Outgoing Message 39. @Test public void order_is_placed_after_request_with_selection() { //OrderHandler orderHandler = mock(OrderHandler.class); OrderHandler orderHandler = new OrderExecutor(); PrepaidTopup prepaidTopup = new PrepaidTopupStand(orderHandler); prepaidTopup.press(5); prepaidTopup.press(0); prepaidTopup.sendRequest(); //verify(orderHandler).placeOrder("50"); assertThat(orderHandler.getOrders()).contains("50"); } Asserting on side effect 40. Asserting on side effect press(key) sendRequest() PrepaidTopup placeOrder(selection) OrderExecutor +10% 41. @Test public void order_is_placed_after_request_with_selection() { OrderHandler orderHandler = new OrderExecutor(); PrepaidTopup prepaidTopup = new PrepaidTopupStand(orderHandler); prepaidTopup.press(5); prepaidTopup.press(0); prepaidTopup.sendRequest(); assertThat(orderHandler.getOrders()).contains("50"); //java.lang.AssertionError expecting to contain: } Asserting on side effect 42. QUERY COMMAND INCOMMING Assert on result Assert on state change OUTGOING Stub, avoid asserting Assert on Mocks 43. Thank You! @milipski