From b79e1230a959d1fec06de3933279d18a34114942 Mon Sep 17 00:00:00 2001 From: Iiro Krankka Date: Mon, 9 Jan 2017 11:16:15 +0200 Subject: [PATCH] Made the tests in MainPresenter be more specific & made the RandomBookGenerator methods not static to make it mockable. --- .idea/modules.xml | 1 - app/build.gradle | 2 ++ .../booklibrary/RecyclerViewAssertions.java | 1 - .../booklibrary/ui/MainActivityTest.java | 5 ++- .../codemate/booklibrary/data/Library.java | 6 ++-- .../booklibrary/data/RandomBookGenerator.java | 6 ++-- .../codemate/booklibrary/ui/MainActivity.java | 10 ++++-- .../booklibrary/ui/MainPresenter.java | 20 ++++++----- .../booklibrary/data/LibraryTest.java | 2 +- .../data/RandomBookGeneratorTest.java | 2 +- .../booklibrary/ui/MainPresenterTest.java | 33 +++++++++++-------- .../booksearch.feature | 6 ++-- 12 files changed, 54 insertions(+), 40 deletions(-) diff --git a/.idea/modules.xml b/.idea/modules.xml index 954c641..efc2759 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -5,7 +5,6 @@ - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 19ad51e..d53ae02 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -27,6 +27,8 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) + androidTestCompile 'org.mockito:mockito-core:2.5.5' + androidTestCompile 'com.linkedin.dexmaker:dexmaker-mockito:2.2.0' androidTestCompile ('com.android.support.test.espresso:espresso-core:2.2.1') { exclude module: 'support-annotations' } diff --git a/app/src/androidTest/java/com/codemate/booklibrary/RecyclerViewAssertions.java b/app/src/androidTest/java/com/codemate/booklibrary/RecyclerViewAssertions.java index ee01a5d..4136359 100644 --- a/app/src/androidTest/java/com/codemate/booklibrary/RecyclerViewAssertions.java +++ b/app/src/androidTest/java/com/codemate/booklibrary/RecyclerViewAssertions.java @@ -13,7 +13,6 @@ import static org.junit.Assert.assertTrue; * Created by ironman on 02/09/16. */ public class RecyclerViewAssertions { - public static ViewAssertion adapterItemCountEquals(int count) { return new ItemCountAssertion(ItemCountAssertion.MODE_EQUALS, count); } diff --git a/app/src/androidTest/java/com/codemate/booklibrary/ui/MainActivityTest.java b/app/src/androidTest/java/com/codemate/booklibrary/ui/MainActivityTest.java index a420f32..da809a8 100644 --- a/app/src/androidTest/java/com/codemate/booklibrary/ui/MainActivityTest.java +++ b/app/src/androidTest/java/com/codemate/booklibrary/ui/MainActivityTest.java @@ -19,7 +19,10 @@ import static com.codemate.booklibrary.RecyclerViewAssertions.adapterItemCountEq import static com.codemate.booklibrary.RecyclerViewAssertions.adapterItemCountLowerThan; /** - * Created by ironman on 02/09/16. + * Some really coarse UI tests. + * + * Check the MainPresenterTest for more specific tests that ensure correct books are + * returned. */ @RunWith(AndroidJUnit4.class) public class MainActivityTest { diff --git a/app/src/main/java/com/codemate/booklibrary/data/Library.java b/app/src/main/java/com/codemate/booklibrary/data/Library.java index 6e7584c..c9483ae 100644 --- a/app/src/main/java/com/codemate/booklibrary/data/Library.java +++ b/app/src/main/java/com/codemate/booklibrary/data/Library.java @@ -39,7 +39,7 @@ public class Library { return results; } - public List findBooksByAuthor(String authorQuery) { + private List findBooksByAuthor(String authorQuery) { List results = new ArrayList<>(); for (Book candidate : inventory) { @@ -54,7 +54,7 @@ public class Library { return results; } - public List findBooksByTitle(String titleQuery) { + private List findBooksByTitle(String titleQuery) { List results = new ArrayList<>(); for (Book candidate : inventory) { @@ -69,7 +69,7 @@ public class Library { return results; } - public List findBooksByYear(String searchedYear) { + private List findBooksByYear(String searchedYear) { List results = new ArrayList<>(); for (Book candidate : inventory) { diff --git a/app/src/main/java/com/codemate/booklibrary/data/RandomBookGenerator.java b/app/src/main/java/com/codemate/booklibrary/data/RandomBookGenerator.java index 04b5932..c211120 100644 --- a/app/src/main/java/com/codemate/booklibrary/data/RandomBookGenerator.java +++ b/app/src/main/java/com/codemate/booklibrary/data/RandomBookGenerator.java @@ -9,8 +9,6 @@ import java.util.List; * Created by ironman on 02/09/16. */ public class RandomBookGenerator { - private RandomBookGenerator() {} - private static final String[] SUBJECTS = { "Chicken", "Pig", "Hippo", "Dinosaur", "Giraffe", "Orangutan", "Bat", "Lion", "Daddy", "Grandpa", "Donald Trump", "Coffee", @@ -40,7 +38,7 @@ public class RandomBookGenerator { * @param howMany how many random books should the generator generate. * @return a list that has as many books as the parameter howMany specifies. */ - public static List generate(int howMany) { + public List generate(int howMany) { List books = new ArrayList<>(); for (int i = 0; i < howMany; i++) { @@ -53,7 +51,7 @@ public class RandomBookGenerator { /** * Generates a random book. */ - public static Book randomBook() { + public Book randomBook() { String title = randomTitle(); String author = randomAuthor(); Date date = randomDate(); diff --git a/app/src/main/java/com/codemate/booklibrary/ui/MainActivity.java b/app/src/main/java/com/codemate/booklibrary/ui/MainActivity.java index f99267c..583e2ce 100644 --- a/app/src/main/java/com/codemate/booklibrary/ui/MainActivity.java +++ b/app/src/main/java/com/codemate/booklibrary/ui/MainActivity.java @@ -1,5 +1,6 @@ package com.codemate.booklibrary.ui; +import android.support.annotation.VisibleForTesting; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; @@ -9,11 +10,14 @@ import android.support.v7.widget.SearchView; import com.codemate.booklibrary.data.Book; import com.codemate.booklibrary.data.Library; import com.codemate.booklibrary.R; +import com.codemate.booklibrary.data.RandomBookGenerator; import java.util.List; public class MainActivity extends AppCompatActivity implements MainView, SearchView.OnQueryTextListener { - private MainPresenter presenter; + @VisibleForTesting + MainPresenter presenter; + private BookAdapter bookAdapter; @Override @@ -23,8 +27,8 @@ public class MainActivity extends AppCompatActivity implements MainView, SearchV initializeViews(); - presenter = new MainPresenter(this, new Library()); - presenter.loadAllBooks(); + presenter = new MainPresenter(this, new Library(), new RandomBookGenerator()); + presenter.fetchBooks(); } private void initializeViews() { diff --git a/app/src/main/java/com/codemate/booklibrary/ui/MainPresenter.java b/app/src/main/java/com/codemate/booklibrary/ui/MainPresenter.java index 38e8eb7..e682008 100644 --- a/app/src/main/java/com/codemate/booklibrary/ui/MainPresenter.java +++ b/app/src/main/java/com/codemate/booklibrary/ui/MainPresenter.java @@ -1,5 +1,7 @@ package com.codemate.booklibrary.ui; +import android.support.annotation.VisibleForTesting; + import com.codemate.booklibrary.data.Book; import com.codemate.booklibrary.data.Library; import com.codemate.booklibrary.data.RandomBookGenerator; @@ -13,27 +15,27 @@ public class MainPresenter { private final MainView mainView; private final Library library; - public MainPresenter(MainView mainView, Library library) { + @VisibleForTesting + RandomBookGenerator bookGenerator; + + public MainPresenter(MainView mainView, Library library, RandomBookGenerator bookGenerator) { this.mainView = mainView; this.library = library; + this.bookGenerator = bookGenerator; } public void searchForBooks(String searchQuery) { List searchResults = library.search(searchQuery); - loadBooks(searchResults); + mainView.showBooks(searchResults); } - public void loadAllBooks() { + public void fetchBooks() { // Populate the library with fake dummy data. In a real app // we would have an interactor that would fetch the books from // a real API. - List books = RandomBookGenerator.generate(45); + List books = bookGenerator.generate(45); library.addBooks(books); - loadBooks(library.getAllBooks()); - } - - public void loadBooks(List books) { - mainView.showBooks(books); + mainView.showBooks(library.getAllBooks()); } } diff --git a/app/src/test/java/com/codemate/booklibrary/data/LibraryTest.java b/app/src/test/java/com/codemate/booklibrary/data/LibraryTest.java index 13250c1..f31c8ee 100644 --- a/app/src/test/java/com/codemate/booklibrary/data/LibraryTest.java +++ b/app/src/test/java/com/codemate/booklibrary/data/LibraryTest.java @@ -11,7 +11,7 @@ import java.util.List; public class LibraryTest { @Test public void addMultipleBooks_PersistsThemInLibrary() { - List books = RandomBookGenerator.generate(3); + List books = new RandomBookGenerator().generate(3); Library library = new Library(); library.addBooks(books); diff --git a/app/src/test/java/com/codemate/booklibrary/data/RandomBookGeneratorTest.java b/app/src/test/java/com/codemate/booklibrary/data/RandomBookGeneratorTest.java index 7030b06..a992422 100644 --- a/app/src/test/java/com/codemate/booklibrary/data/RandomBookGeneratorTest.java +++ b/app/src/test/java/com/codemate/booklibrary/data/RandomBookGeneratorTest.java @@ -14,7 +14,7 @@ import static org.junit.Assert.assertNotNull; public class RandomBookGeneratorTest { @Test public void generatingRandomBooks_ReturnsNonEmptyBookList() { - List books = RandomBookGenerator.generate(15); + List books = new RandomBookGenerator().generate(15); assertEquals(15, books.size()); diff --git a/app/src/test/java/com/codemate/booklibrary/ui/MainPresenterTest.java b/app/src/test/java/com/codemate/booklibrary/ui/MainPresenterTest.java index a6848a0..9643c9b 100644 --- a/app/src/test/java/com/codemate/booklibrary/ui/MainPresenterTest.java +++ b/app/src/test/java/com/codemate/booklibrary/ui/MainPresenterTest.java @@ -9,9 +9,12 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.sql.Date; +import java.util.Arrays; import java.util.List; -import static org.mockito.Matchers.anyString; +import static java.util.Collections.singletonList; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -19,36 +22,40 @@ import static org.mockito.Mockito.when; * Created by ironman on 02/09/16. */ public class MainPresenterTest { + private static final List DUMMY_BOOKS = Arrays.asList( + new Book("Sample book one", "John Doe", Date.valueOf("2000-10-25")), + new Book("Sample book two", "Jane Doe", Date.valueOf("2016-01-01")), + new Book("Sample book three", "Some One", Date.valueOf("2005-12-12")) + ); + @Mock private MainView mainView; @Mock - private Library library; + private RandomBookGenerator bookGenerator; private MainPresenter presenter; - private List randomBooks; @Before public void setUp() { MockitoAnnotations.initMocks(this); - presenter = new MainPresenter(mainView, library); - randomBooks = RandomBookGenerator.generate(5); + when(bookGenerator.generate(anyInt())).thenReturn(DUMMY_BOOKS); + presenter = new MainPresenter(mainView, new Library(), bookGenerator); } @Test - public void searchForBooks_ShowsThemInUI() { - when(library.search(anyString())).thenReturn(randomBooks); - presenter.searchForBooks("test_search"); + public void searchForBooks_WhenSearchingByAuthorJohn_ShowsFirstBookInUI() { + presenter.fetchBooks(); + presenter.searchForBooks("John"); - verify(mainView).showBooks(randomBooks); + verify(mainView).showBooks(singletonList(DUMMY_BOOKS.get(0))); } @Test - public void loadAllBooks_ShowsThemInUI() { - when(library.getAllBooks()).thenReturn(randomBooks); - presenter.loadAllBooks(); + public void fetchBooks_LoadsAll_AndShowsThemInUI() { + presenter.fetchBooks(); - verify(mainView).showBooks(randomBooks); + verify(mainView).showBooks(DUMMY_BOOKS); } } diff --git a/app/src/test/resources/com.codemate.booklibrary/booksearch.feature b/app/src/test/resources/com.codemate.booklibrary/booksearch.feature index 02d45f7..ccb6cb7 100644 --- a/app/src/test/resources/com.codemate.booklibrary/booksearch.feature +++ b/app/src/test/resources/com.codemate.booklibrary/booksearch.feature @@ -4,14 +4,14 @@ Feature: Book Search Background: Given the library has a book with title "How to be awesome", written by "Iiro Krankka", published in 16 May 2016 And a book with title "My life as an awesome guy", written by "Iiro Krankka", published in 27 July 2016 - And a book with title "I think my teacher is an asshat", written by "John Doe", published in 01 January 2010 + And a book with title "I think my teacher is cool", written by "John Doe", published in 01 January 2010 Scenario: List all books When the customer wants to know all books in the library Then 3 books should be found And Book 1 should have the title "How to be awesome" And Book 2 should have the title "My life as an awesome guy" - And Book 3 should have the title "I think my teacher is an asshat" + And Book 3 should have the title "I think my teacher is cool" Scenario: Search books by year When the customer searches for books published in year 2016 @@ -39,5 +39,5 @@ Feature: Book Search Examples: | Title Search | Number of Results | Found Books | | "Awesome" | 2 | "How to be awesome" and "My life as an awesome guy" | - | "asshat" | 1 | "I think my teacher is an asshat" | + | "cool" | 1 | "I think my teacher is cool" | | "How to be" | 1 | "How to be awesome" | \ No newline at end of file