Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Desenvolvimento guiado por testes no Android co...

Desenvolvimento guiado por testes no Android com MVP.

Avatar for Vinícius Soares

Vinícius Soares

May 11, 2017
Tweet

More Decks by Vinícius Soares

Other Decks in Technology

Transcript

  1. TDD - Test Driven Development Write a test that fails

    Make the code work Remove redundancy
  2. Mockito class Database { String getFirstProductName() { /* ... */

    }; /* ... */ } Database mockDatabase = Mockito.mock(Database.class);
  3. Mockito class Database { String getFirstProductName() { /* ... */

    }; /* ... */ } Database mockDatabase = Mockito.mock(Database.class); System.out.print(mockDatabase.getFirstProductName()); // Prints: null Mockito.verify(mockDatabase).getFirstProductName();
  4. Mockito class Database { String getFirstProductName() { /* ... */

    }; /* ... */ } Database mockDatabase = Mockito.mock(Database.class);
  5. Mockito class Database { String getFirstProductName() { /* ... */

    }; /* ... */ } Database mockDatabase = Mockito.mock(Database.class); Mockito.when(mockDatabase.getFirstProductName()).thenReturn("Google Pixel"); System.out.print(mockDatabase.getFirstProductName()); // Prints: Google Pixel Mockito.verify(mockDatabase).getFirstProductName();
  6. Mockito class Database { String getFirstProductName() { /* ... */

    }; /* ... */ } Database mockDatabase = Mockito.mock(Database.class); Mockito.when(mockDatabase.getFirstProductName()).thenReturn("Google Pixel"); System.out.print(mockDatabase.getFirstProductName()); // Prints: Google Pixel Mockito.verify(mockDatabase).getFirstProductName();
  7. Planning • Mostrar a lista de artigos. • Mostrar um

    Empty State se a lista estiver vazia.
  8. Tests @Test public void loadArticlesReturnsArticles() { List<Article> articles = new

    ArrayList<>(); articles.add(/* ... */); articles.add(/* ... */); }
  9. Tests @Test public void loadArticlesReturnsArticles() { List<Article> articles = new

    ArrayList<>(); articles.add(/* ... */); articles.add(/* ... */); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); }
  10. Tests @Test public void loadArticlesReturnsArticles() { List<Article> articles = new

    ArrayList<>(); articles.add(/* ... */); articles.add(/* ... */); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); presenter.loadArticles(); }
  11. Tests @Test public void loadArticlesReturnsArticles() { List<Article> articles = new

    ArrayList<>(); articles.add(/* ... */); articles.add(/* ... */); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); presenter.loadArticles(); Mockito.verify(mockView).showArticles(articles); }
  12. Tests @Test public void loadArticlesReturnsArticles() { List<Article> articles = new

    ArrayList<>(); articles.add(/* ... */); articles.add(/* ... */); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); presenter.loadArticles(); Mockito.verify(mockView).showArticles(articles); Mockito.verify(mockView, never()).showEmptyState(); }
  13. Tests @Test public void loadArticlesReturnsEmptyList() { List<Article> articles = new

    ArrayList<>(); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); }
  14. Tests @Test public void loadArticlesReturnsEmptyList() { List<Article> articles = new

    ArrayList<>(); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); presenter.loadArticles(); }
  15. Tests @Test public void loadArticlesReturnsEmptyList() { List<Article> articles = new

    ArrayList<>(); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); presenter.loadArticles(); Mockito.verify(mockView).showEmptyState(); Mockito.verify(mockView, never()).showArticles(ArgumentMatchers.anyList()); }
  16. class ArticlesActivity extends AppCompatActivity implements ArticlesView { ArticlesPresenter presenter; protected

    void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); presenter = new ArticlesPresenter(UserRepository.getInstance()); /* Use dagger */ presenter.attachView(this); } protected onDestroy() { super.onDestroy(); presenter.detachView(); } public void showArticles(List<Articles> articles) { /* ... */ } public void showEmptyState() { /* ... */ } }
  17. Presenter class ArticlesPresenter { private ArticlesView view; public void attachView(ArticlesView

    view) { this.view = view; } public void detachView() { this.view = null; } }
  18. Presenter class ArticlesPresenter { private View view; private ArticlesRepository repository;

    public ArticlesPresenter(ArticlesRepository repository) { this.repository = repository; } public void attachView(View view) { /* ... */ } public void detachView() { /* ... */ } }
  19. Presenter public void detachView() { /* ... */ } public

    void loadArticles() { repository.getArticles() /* ... */ .subscribe(articles -> { if (articles.isEmpty()) view.showArticlesEmptyState(); else view.showArticles(articles); }); } }
  20. Model - Repository Pattern class ArticlesRepository { public Observable<List<Article>> getArticles()

    { Observable<List<Article>> memory = /* ... */; Observable<List<Article>> database = /* ... */; Observable<List<Article>> api = /* ... */; return Observable .concat(memory, database, api) .first(); } }
  21. Próximos passos • Clean Architecture • Espresso & UiAutomator. •

    Cobertura de Testes • Code Analysis tools • Continuous integration