built-in fake objects
TRANSCRIPT
![Page 1: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/1.jpg)
/29@yegor256 1
Built-in Fake Objects
Yegor Bugayenko
![Page 2: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/2.jpg)
/29@yegor256 2
“Mock objects are simulated objects that mimic the behavior of
real objects in controlled ways”
![Page 3: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/3.jpg)
/29@yegor256 3
FakeObjects
Mocking Frameworks
![Page 4: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/4.jpg)
/29@yegor256 4
static String report(User user) { return String.format( “Balance of %s is %d USD”, user.profile().name(), user.account().balance().usd() ); }
![Page 5: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/5.jpg)
/29@yegor256 5
interface Profile { String name(); }
interface User { Profile profile(); Account account(); }
interface Account { Balance balance(); }
interface Balance { int usd(); }
![Page 6: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/6.jpg)
/29@yegor256 6
@Test void printsReport() { User user = mock(User.class); assertThat( Foo.report(user), containsString(“Balance of”) ); }
Mockito
![Page 7: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/7.jpg)
/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”) ); }
![Page 8: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/8.jpg)
/29@yegor256 8
1. verbosity
![Page 9: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/9.jpg)
/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() ); }
![Page 10: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/10.jpg)
/29@yegor256 10
2. code duplication
![Page 11: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/11.jpg)
/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”) ); }
![Page 12: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/12.jpg)
/29@yegor256 12
3. complexity
![Page 13: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/13.jpg)
/29@yegor256 13
example!!
![Page 14: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/14.jpg)
/29@yegor256 14
4. fragility
because
of coupl
ing
![Page 15: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/15.jpg)
/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() ); }
![Page 16: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/16.jpg)
/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() ); }
![Page 17: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/17.jpg)
/29@yegor256 17
“Unit tests are your safety net”
![Page 18: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/18.jpg)
/29@yegor256 18
false positive
![Page 19: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/19.jpg)
/29@yegor256 19
throw-away tests
![Page 20: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/20.jpg)
/29@yegor256 20
a solution?fake objects!
![Page 21: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/21.jpg)
/29@yegor256 21
interface User { Profile profile(); Account account(); class Fake { Fake(String name, int balance) { // ... } // ... } }
![Page 22: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/22.jpg)
/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?
![Page 23: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/23.jpg)
/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”) ); }
![Page 24: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/24.jpg)
/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”) ); }
![Page 25: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/25.jpg)
/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”) ); }
![Page 26: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/26.jpg)
/29@yegor256 26
no throw-away tests any more
![Page 27: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/27.jpg)
/29@yegor256 27
always ship themtogether!
![Page 28: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/28.jpg)
/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)) ); } }
![Page 29: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/29.jpg)
/29@yegor256 29
FakeObjects
Mocking Frameworks
![Page 30: Built-in Fake Objects](https://reader031.vdocuments.mx/reader031/viewer/2022022202/587c16c31a28abb5068b470b/html5/thumbnails/30.jpg)
/29@yegor256 30
Section 2.8
Don’t mock; use fakes