Top Banner
/38 @yegor256 1 Yegor Bugayenko Object-Oriented JUnit Tests
38

Object-Oriented JUnit Tests

Jan 22, 2018

Download

Technology

Yegor Bugayenko
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Object-Oriented JUnit Tests

/38@yegor256 1

Yegor Bugayenko

Object-Oriented JUnit Tests

Page 2: Object-Oriented JUnit Tests

/38@yegor256 2

Why OOP?

Page 3: Object-Oriented JUnit Tests

/38@yegor256 3

yegor256/hangman11

@funivan

Page 4: Object-Oriented JUnit Tests

/38@yegor256 4

Volume 2

$20Free shipment

Page 5: Object-Oriented JUnit Tests

/38@yegor256 5Unit testing anti-patterns:Happy Path Tests Validation and Boundary Easy Tests The Giant The Cuckoo The Conjoined Twins The Slow Poke Anal Probe Test It All Line Hitter Wait and See The Silent Catcher Chain Gang

The Mockery The Free Ride The Local Hero Wet Floor The Flickering Test The Environmental Vandal Second Class Citizens The Secret Catcher Logic in Tests Code Matching Misleading Tests Not Asserting Asserting on Not-Null

Forty Foot Pole Test With No Name Excessive Setup The Dead Tree The Turing Test The Mother Hen The Sleeper The Butterfly Doppelgänger The Inspector Structured Inspection The Cupcake

Page 6: Object-Oriented JUnit Tests

/38@yegor256

Dependencies

6

are evil

Unbreakable

Page 7: Object-Oriented JUnit Tests

/38@yegor256 7

class Book { private int id; String title() { return Database.getInstance().fetch( “SELECT title FROM book WHERE id=?”, this.id ); } } String title = new Book().title();

Page 8: Object-Oriented JUnit Tests

/38@yegor256 8

Book

BookTest

DatabaseSomething

Page 9: Object-Oriented JUnit Tests

/38@yegor256 9

class Book { private int id; String title() { return DbUtils.fetch( “SELECT title FROM book WHERE id=?”, this.id ); } }

static

Johan Haleby

Page 10: Object-Oriented JUnit Tests

/38@yegor256 10

class Book { private int id; String title() { return Database.getInstance().fetch( “SELECT title FROM book WHERE id=?”, this.id ); } }

global

Page 11: Object-Oriented JUnit Tests

/38@yegor256 11

class DbUtils { private static int port; static String fetch(String sql) { // .. } }

class Database { private static Database INSTANCE; private int port; private Database() {} static Database getInstance() { if (Database.INSTANCE == null) { Database.INSTANCE = new Database(); } return Database.INSTANCE; } String fetch(String sql) { // .. } }

Page 12: Object-Oriented JUnit Tests

/38@yegor256 12

class DbUtils { private static int port; static String fetch(String sql) { // .. } }

class Database { private static Database INSTANCE; private int port; private Database() {} static Database getInstance() { if (Database.INSTANCE == null) { Database.INSTANCE = new Database(); } return Database.INSTANCE; } static void setInstance(Database db) { Database.INSTANCE = db; } String fetch(String sql) { // .. } }

Page 13: Object-Oriented JUnit Tests

/38@yegor256 13

class Book { private int id; String title() { return new Database().fetch( “SELECT title FROM book WHERE id=?”, this.id ); } }

new

Page 14: Object-Oriented JUnit Tests

/38@yegor256 14

class Book { private int id; private Database database; Book() { this(new Database()); } Book(Database db) { this.database = db; } String title() { return this.database.fetch( “SELECT title FROM book WHERE id=?”, this.id ); } }

Dependency Injection

Page 15: Object-Oriented JUnit Tests

/38@yegor256 15

new Book(new NotRealDatabase());

class NotRealDatabase implements Database { // ... }

interfaces

@Override

Page 16: Object-Oriented JUnit Tests

/38@yegor256 16

static evil!

singletonsnewinterface-less

Page 17: Object-Oriented JUnit Tests

/38@yegor256

Mocking

17

is evil

Ad hoc

Page 18: Object-Oriented JUnit Tests

/38@yegor256 18

static import org.mockito.Mockito.*; class BookTest { @Test public canFetchTitleFromDatabase() { Database db = mock(Database.class); doReturn(“UML Distilled”).when(db).fetch( “SELECT title FROM book WHERE id=?”, 123 ); Book book = new Book(db, 123); assert book.title().equals(“UML Distilled”); } }

Page 19: Object-Oriented JUnit Tests

/38@yegor256 19

mocking

algorithm

Page 20: Object-Oriented JUnit Tests

/38@yegor256 20

Book

BookTest

db

assumptions

Page 21: Object-Oriented JUnit Tests

/38@yegor256 21

Safety net.(c) By John M, CC BY-SA 2.0

Page 22: Object-Oriented JUnit Tests

/38@yegor256 22

static import org.mockito.Mockito.*; class BookTest { @Test public canFetchTitleFromDatabase() { Database db = mock(Database.class); doReturn(“UML Distilled”).when(db).fetch( “SELECT title FROM book WHERE id=?”, 123 ); Book book = new Book(db, 123); assert book.title().equals(“UML Distilled”); } }

class Book { private int id; private Database database; Book(Database db, int i) { this.database = db; this.id = i; } String title() { return this.database.fetch( “SELECT title FROM book WHERE id=?”, this.id ); } }

Page 23: Object-Oriented JUnit Tests

/38@yegor256 23

False positives.

Page 24: Object-Oriented JUnit Tests

/38@yegor256 24

Fakes or doubles.

Page 25: Object-Oriented JUnit Tests

/38@yegor256 25

class BookTest { @Test public canFetchTitleFromDatabase() { Book book = new Book( new FakeDatabase(), 123 ); assert book.title().equals(“UML Distilled”); } }

class Book { private int id; private Database database; Book(Database db, int i) { this.database = db; this.id = i; } String title() { return this.database.fetch( “SELECT title FROM book WHERE id=?”, this.id ); } }

Page 26: Object-Oriented JUnit Tests

/38@yegor256 26

class BookTest { @Test public canFetchTitleFromDatabase() { Book book = new Book( new FakeDatabase() .withTitle(123, “UML Distilled”) .withTitle(1, “Elegant Objects”) .withUser(“Peter Pan”), 123 ); assert book.title().equals(“UML Distilled”); } }

Page 27: Object-Oriented JUnit Tests

/38@yegor256 27

Ad hoc mocking.

Fakes.

Page 28: Object-Oriented JUnit Tests

/38@yegor256

Algorithms

28

are evil

In-method

Maybe!

Page 29: Object-Oriented JUnit Tests

/38@yegor256 29

cactoos

www.cactoos.org

Page 30: Object-Oriented JUnit Tests

/38@yegor256 30

class BookTest { @Test public canBuildURL() { Book book = new Book(); book.setLanguage(Locale.RUSSIAN); book.setEncoding(“UTF-8”); book.setTitle(“Дон Кихот”); assert book.getURL().contains(“%D0%94%”); } }

procedural!

Page 31: Object-Oriented JUnit Tests

/38@yegor256 31

HamcrestAn anagram for “matchers”.

Page 32: Object-Oriented JUnit Tests

/38@yegor256 32

A test method must have nothing but a single statement:

assertThat()

Page 33: Object-Oriented JUnit Tests

/38@yegor256 33

assertThat(book, hasTitle(“UML Distilled”));

“We assert that the book behaves as if it has a title.”

Page 34: Object-Oriented JUnit Tests

/38@yegor256 34

assertThat( book, hasURL( hasPath( containsString( equalTo(“%D0%94%”) ) ) ) );

We assert thatthe book behaves as if it has a URL that behaves as if it has a path that behaves as if it contains a string that behaves as if it is equal to “%D0%94%”.

Page 35: Object-Oriented JUnit Tests

/38@yegor256 35

Page 36: Object-Oriented JUnit Tests

/38@yegor256 36

Page 37: Object-Oriented JUnit Tests

/38@yegor256 37

shorter test methods

why?!

immutable objectsshare matchers

Page 38: Object-Oriented JUnit Tests

/38@yegor256 38

Quality Award.

$4096