O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Rx java testing patterns

366 visualizações

Publicada em

Rx java testing patterns

Publicada em: Software
  • Seja o primeiro a comentar

Rx java testing patterns

  1. 1. RxJava Testing Patterns Android Taipei 2019 March
  2. 2. Outline 1. Brief introduction about Unit testing 2. Stub with Observable 3. Verify an Observable 4. LifeCycle Testing 5. Test with time
  3. 3. Unit testing 1. Arrange, Act, Assert 2. Don’t ask “How to test this code?” 3. You should ask “What’s our requirement?” or “What’s the use case here?” 4. Just test one thing, don’t try to verify two different things at the same time.
  4. 4. Stub with Observable
  5. 5. class NotePresenter(private val noteView: NoteView, private val noteRepo: NoteRepo) { fun onStart() { noteRepo.getAllNotes() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { notes -> noteView.showNotes(notes) } } }
  6. 6. class NotePresenter(private val noteView: NoteView, private val noteRepo: NoteRepo) { fun onStart() { noteRepo.getAllNotes() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { notes -> noteView.showNotes(notes) } } }
  7. 7. class NotePresenter(private val noteView: NoteView, private val noteRepo: NoteRepo, private val uiScheduler: Scheduler, private val ioScheduler: Sched..) { fun onStart() { noteRepo.getAllNotes() .subscribeOn(ioScheduler) .observeOn(uiScheduler) .subscribe { notes -> noteView.showNotes(notes) } } }
  8. 8. class NotePresenter(private val noteView: NoteView, private val noteRepo: NoteRepo, private val uiScheduler: Scheduler, private val ioScheduler: Sched..) { fun onStart() { noteRepo.getAllNotes() .subscribeOn(ioScheduler) .observeOn(uiScheduler) .subscribe { notes -> noteView.showNotes(notes) } } }
  9. 9. Choose a Mock library - Mockito - MockK - Mockito-kotlin - ...
  10. 10. Choose a Mock library - Mockito - MockK - Mockito-kotlin - ...
  11. 11. class PresenterTest { private val noteView: NoteView = mockk() private val noteRepo: NoteRepo = mockk() private val mockScheduler = Schedulers.trampoline() @Test fun noteTest() { val presenter = NotePresenter(noteView, noteRepo, mockScheduler, mockScheduler) val notes = listOf(Note("GTD")) every { noteRepo.getAllNotes() } returns Observable.just(notes) presenter.onStart() verify { noteView.showNotes(notes) } } }
  12. 12. class PresenterTest { private val noteView: NoteView = mockk() private val noteRepo: NoteRepo = mockk() private val mockScheduler = Schedulers.trampoline() @Test fun noteTest() { val presenter = NotePresenter(noteView, noteRepo, mockScheduler, mockScheduler) val notes = listOf(Note("GTD")) every { noteRepo.getAllNotes() } returns Observable.just(notes) presenter.onStart() verify { noteView.showNotes(notes) } } }
  13. 13. class PresenterTest { private val noteView: NoteView = mockk() private val noteRepo: NoteRepo = mockk() private val mockScheduler = Schedulers.trampoline() @Test fun noteTest() { val presenter = NotePresenter(noteView, noteRepo, mockScheduler, mockScheduler) val notes = listOf(Note("GTD")) every { noteRepo.getAllNotes() } returns Observable.just(notes) presenter.onStart() verify { noteView.showNotes(notes) } } }
  14. 14. class PresenterTest { private val noteView: NoteView = mockk() private val noteRepo: NoteRepo = mockk() private val mockScheduler = Schedulers.trampoline() @Test fun noteTest() { val presenter = NotePresenter(noteView, noteRepo, mockScheduler, mockScheduler) val notes = listOf(Note("GTD")) every { noteRepo.getAllNotes() } returns Observable.just(notes) presenter.onStart() verify { noteView.showNotes(notes) } } }
  15. 15. Verify An Observable
  16. 16. class NoteViewModel(private val noteRepo: NoteRepo) { val noteSubject = BehaviorSubject.create<List<Note>>() fun onStart() { noteRepo.getAllNotes() .subscribe { notes -> noteSubject.onNext(notes) } } }
  17. 17. class NoteViewModel(private val noteRepo: NoteRepo) { val noteSubject = BehaviorSubject.create<List<Note>>() fun onStart() { noteRepo.getAllNotes() .subscribe { notes -> noteSubject.onNext(notes) } } }
  18. 18. class NoteViewModelTest { private val noteRepo: NoteRepo = mockk() @Test fun noteTest() { val noteViewModel = NoteViewModel(noteRepo) val notes = listOf(Note("GTD")) every { noteRepo.getAllNotes() } returns Observable.just(notes) noteViewModel.onStart() noteViewModel.noteSubject .test() .assertValue(notes) } }
  19. 19. class NoteViewModelTest { private val noteRepo: NoteRepo = mockk() @Test fun noteTest() { val noteViewModel = NoteViewModel(noteRepo) val notes = listOf(Note("GTD")) every { noteRepo.getAllNotes() } returns Observable.just(notes) noteViewModel.onStart() noteViewModel.noteSubject .test() .assertValue(notes) } }
  20. 20. Assert API
  21. 21. class NoteViewModelTest { private val noteRepo: NoteRepo = mockk() @Test fun noteTest() { val noteViewModel = NoteViewModel(noteRepo) val notes = listOf(Note("GTD")) every { noteRepo.getAllNotes() } returns Observable.just(notes) noteViewModel.onStart() noteViewModel.noteSubject .test() .assertValue(notes) } }
  22. 22. class NoteViewModelTest { private val noteRepo: NoteRepo = mockk() @Test fun noteTest() { val noteViewModel = NoteViewModel(noteRepo) val notes = listOf(Note("GTD")) every { noteRepo.getAllNotes() } returns Observable.just(notes) noteViewModel.onStart() noteViewModel.noteSubject .test() .assertValue(notes) } }
  23. 23. LifeCycle Testing
  24. 24. How to test disposables?
  25. 25. What we want? 1. Finish test subject’s life cycle 2. Send a fake event by stub object 3. Test subject should not have any reaction
  26. 26. @Test fun `after onStop should not receive any data`() { val noteViewModel = NoteViewModel(noteRepo) val notes = listOf(Note("GTD")) val repoNotesSubject = PublishSubject.create<List<Note>>() every { noteRepo.getAllNotes() } returns repoNotesSubject noteViewModel.onStart() noteViewModel.onStop() repoNotesSubject.onNext(notes) noteViewModel.noteSubject .test() .assertNoValues() }
  27. 27. @Test fun `after onStop should not receive any data`() { val noteViewModel = NoteViewModel(noteRepo) val notes = listOf(Note("GTD")) val repoNotesSubject = PublishSubject.create<List<Note>>() every { noteRepo.getAllNotes() } returns repoNotesSubject noteViewModel.onStart() noteViewModel.onStop() repoNotesSubject.onNext(notes) noteViewModel.noteSubject .test() .assertNoValues() }
  28. 28. @Test fun `after onStop should not receive any data`() { val noteViewModel = NoteViewModel(noteRepo) val notes = listOf(Note("GTD")) val repoNotesSubject = PublishSubject.create<List<Note>>() every { noteRepo.getAllNotes() } returns repoNotesSubject noteViewModel.onStart() noteViewModel.onStop() repoNotesSubject.onNext(notes) noteViewModel.noteSubject .test() .assertNoValues() }
  29. 29. Test with time
  30. 30. Let’s look the code first https://gist.github.com/hungyanbin/e93fd42aea8d75f135aa3d7bc6b96598
  31. 31. Different approach for mocking Scheduler 1. Dependency injection 2. RxJavaPlugins.setXXXSchedulerHandler 3. Service locator
  32. 32. Resources 1. Testing asynchronous RxJava code using Mockito 2. Unit Testing asynchronous RxJava code
  33. 33. Summary 1. Brief introduction about Unit testing 2. Stub with Observable 3. Verify an Observable 4. LifeCycle Testing 5. Test with time
  34. 34. Unit testing 1. Arrange, Act, Assert 2. Don’t ask “How to test this code?” 3. You should ask “What’s our requirement?” or “What’s the use case here?” 4. Just test one thing, don’t try to verify two different things at the same time.
  35. 35. Any Questions?

×