Skip to content

Instantly share code, notes, and snippets.

@heridev
Last active August 11, 2018 15:24
Show Gist options
  • Save heridev/b64a8b20f93c0d39a8c8a4eb7c782989 to your computer and use it in GitHub Desktop.
Save heridev/b64a8b20f93c0d39a8c8a4eb7c782989 to your computer and use it in GitHub Desktop.
Refactoring the app into MVP : Fourth part - Exceptions

Let's start changing the repository to trigger an exception(typo in the orderby clause):

DatabaseBooksRepository.java

public class DatabaseBooksRepository implements BooksRepository {
  private final DatabaseHelper databaseHelper;
  public DatabaseBooksRepository(Content context) {
   databaseHelper = OpenHelperManager.getHelper(context, DatabaseHelper.class);
  }

  @Override
  public List<Book> getBooks(){
    try{
      return databaseHelper.getbookDaO().queryBuilder()
               .orderBy("orderXXX", tru)
               .query();
    } catch {
      throw new RuntimeException("boom");
    }
  }
}

the new scenario for testing it would look like this: BooksActivityPresenterTest.java

import org.junit.Test;
import org.junit.Asserts;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;

public class BooksActivityPresenterTest {
 
 @Rule
 public MockitoRule mockitoRule = MockitoJUnit.rule();

 @Mock
 BooksRepository booksRepository;

 @Mock
 BooksActivityView view;
 
 BooksActivityPresenter presenter;

 @Before
 public void setUp() { presenter = new BooksActivityPresenter(view, booksRepository); }

 @Test
 public void shouldHandleAnException() {

  Mockito.when(booksRepository.getBooks())
                              .thenThrown(new RuntimeException("boom")));
  
  presenter.loadBooks();

  Mockito.verify(view).displayError();
 }
}

Now we need to implement this new displayError method: BooksActivityView.js

public interface BookActivityView {
  void displayBooks(List<Book> bookList);

  void displayNoBooks();

  void displayError();
}

And as our BooksActivity implements this interface we need to declare there our view method and the logic for that:

BooksActivity.java

public class BooksActivity extend BaseActivity implements BooksActivityView {
  private BooksActivityPresenter presenter;
  @override
  protected void onCreate(...){
    ....
  }

  @Override public void displayBooks(List<book> bookList) {
    ...
  }

  @Override public void displayNoBooks() {
    ...
  };

  @Override public void displayError() {
    Toast.makeText(this, "Errror accessing data", Toast.LENGTH_SHORT).show();
  };
}

And we need to reflect this change on the main: BooksActivityPresenter.java

public class BooksActivityPresenter {
  public BooksActivityPresenter(BooksActivityView view, BooksRepository booksRepository) {
    this.view = view;
    this.booksRepository = booksRepository
  }

  public void loadBooks(){
   List<Book> listBooks;
   try {
     listBooks = booksRepository.getBooks();
     // Here the presenter does not know anything about the repository
     // the presenter just wait for getting an array of values and that's it
     if(listBooks.isEmpty()){
       view.displayNoBooks();
     } else {
       view.displayBooks(bookList);
     }
   } catch(Exception e) {
     view.displayError();
   }

  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment