Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Built-in Fake Objects

898 views

Published on

Øredev 2016; Malmö, Sweden; 10 November 2016; video is here: https://www.youtube.com/watch?v=EDKbYVEInMU

Published in: Software
  • Be the first to comment

Built-in Fake Objects

  1. 1. /29@yegor256 1 Built-in Fake Objects Yegor Bugayenko
  2. 2. /29@yegor256 2 “Mock objects are simulated objects that mimic the behavior of real objects in controlled ways”
  3. 3. /29@yegor256 3 Fake
 Objects Mocking Frameworks
  4. 4. /29@yegor256 4 static String report(User user) { return String.format( “Balance of %s is %d USD”, user.profile().name(), user.account().balance().usd() ); }
  5. 5. /29@yegor256 5 interface Profile { String name(); } interface User { Profile profile(); Account account(); } interface Account { Balance balance(); } interface Balance { int usd(); }
  6. 6. /29@yegor256 6 @Test void printsReport() { User user = mock(User.class); assertThat( Foo.report(user), containsString(“Balance of”) ); } Mockito
  7. 7. /29@yegor256 7 @Test void printsReport() { Profile profile = mock(Profile.class); Account account = mock(Account.class); doReturn(“Jeffrey”).when(account).name(); Balance balance = mock(Balance.class); doReturn(123).when(balance).usd(); doReturn(balance).when(account).balance(); User user = mock(User.class); doReturn(profile).when(user).profile(); doReturn(account).when(user).account(); assertThat( Foo.report(user), containsString(“Balance of Jeffrey is 123 USD”) ); }
  8. 8. /29@yegor256 8 1. verbosity
  9. 9. /29@yegor256 9 @Test void printsReport() { Profile profile = mock(Profile.class); Account account = mock(Account.class); doReturn(“Jeffrey”).when(account).name(); Balance balance = mock(Balance.class); doReturn(123).when(balance).usd(); doReturn(balance).when(account).balance(); User user = mock(User.class); doReturn(profile).when(user).profile(); doReturn(account).when(user).account(); assertThat( Foo.report(user), containsString(“Balance of Jeffrey is 123 USD”) ); } String report(User user) { return String.format( “Balance of %s is %d USD”, user.profile().name(), user.account().balance().usd() ); }
  10. 10. /29@yegor256 10 2. code duplication
  11. 11. /29@yegor256 11 @Test void reportIncludesUserName() { Profile profile = mock(Profile.class); Account account = mock(Account.class); doReturn(“Jeffrey”).when(account).name(); Balance balance = mock(Balance.class); doReturn(balance).when(account).balance(); User user = mock(User.class); doReturn(profile).when(user).profile(); doReturn(account).when(user).account(); assertThat( Foo.report(user), containsString(“Jeffrey”) ); } @Test void reportIncludesBalanceInUSD() { Profile profile = mock(Profile.class); Account account = mock(Account.class); Balance balance = mock(Balance.class); doReturn(123).when(balance).usd(); doReturn(balance).when(account).balance(); User user = mock(User.class); doReturn(profile).when(user).profile(); doReturn(account).when(user).account(); assertThat( Foo.report(user), containsString(“123 USD”) ); }
  12. 12. /29@yegor256 12 3. complexity
  13. 13. /29@yegor256 13 example!!
  14. 14. /29@yegor256 14 4. fragility because of coupling
  15. 15. /29@yegor256 15 @Test void printsReport() { Profile profile = mock(Profile.class); Account account = mock(Account.class); doReturn(“Jeffrey”).when(account).name(); Balance balance = mock(Balance.class); doReturn(123).when(balance).usd(); doReturn(balance).when(account).balance(); User user = mock(User.class); doReturn(profile).when(user).profile(); doReturn(account).when(user).account(); assertThat( Foo.report(user), containsString(“Balance of Jeffrey is 123 USD”) ); } String report(User user) { return String.format( “Balance of %s is %d USD”, user.profile().name(), user.account().balance().usd() ); }
  16. 16. /29@yegor256 16 @Test void printsReport() { Profile profile = mock(Profile.class); Account account = mock(Account.class); doReturn(“Jeffrey”).when(account).name(); Balance balance = mock(Balance.class); doReturn(123).when(balance).usd(); doReturn(balance).when(account).balance(); User user = mock(User.class); doReturn(profile).when(user).profile(); doReturn(account).when(user).account(); assertThat( Foo.report(user), containsString(“Balance of Jeffrey is 123 USD”) ); } String report(User user) { return String.format( “Balance of %s is %d USD”, user.profile().name(), user.account().usd() ); }
  17. 17. /29@yegor256 17 “Unit tests are your safety net”
  18. 18. /29@yegor256 18 false positive
  19. 19. /29@yegor256 19 throw-away tests
  20. 20. /29@yegor256 20 a solution?
 fake objects!
  21. 21. /29@yegor256 21 interface User { Profile profile(); Account account(); class Fake { Fake(String name, int balance) { // ... } // ... } }
  22. 22. /29@yegor256 22 @Test void printsReport() { User user = new User.Fake(“Jeffrey”, 123); assertThat( Foo.report(user), containsString(“Balance of Jeffrey is 123 USD”) ); } verbosity?
  23. 23. /29@yegor256 23 @Test void reportIncludesUserName() { User user = new User.Fake(“Jeffrey”); assertThat( Foo.report(user), containsString(“Jeffrey”) ); } code duplication? @Test void reportIncludesBalanceInUSD() { User user = new User.Fake(123); assertThat( Foo.report(user), containsString(“123 USD”) ); }
  24. 24. /29@yegor256 24 @Test void reportIncludesUserName() { User user = new User.Fake(“Jeffrey”); assertThat( Foo.report(user), containsString(“Jeffrey”) ); } complexity? @Test void reportIncludesBalanceInUSD() { User user = new User.Fake(123); assertThat( Foo.report(user), containsString(“123 USD”) ); }
  25. 25. /29@yegor256 25 String report(User user) { return String.format( “Balance of %s is %d USD”, user.profile().name(), user.account().balance().usd() ); } fragility? @Test void reportIncludesBalanceInUSD() { User user = new User.Fake(123); assertThat( Foo.report(user), containsString(“123 USD”) ); }
  26. 26. /29@yegor256 26 no throw-away tests any more
  27. 27. /29@yegor256 27 always ship them
 together!
  28. 28. /29@yegor256 28 interface User { Profile profile(); Account account(); class Fake { } } class UserTest { @Test void hasBalance() { User user = new User.Fake(123); assertThat( user.account().balance().usd(), not(equalTo(0)) ); } }
  29. 29. /29@yegor256 29 Fake
 Objects Mocking Frameworks
  30. 30. /29@yegor256 30 Section 2.8 Don’t mock; use fakes

×