android - How do I make my activity use testing data? -


i have application displays data (posts) web api.

  • a background service syncs data @ unknown time , saves it.
  • when visiting main activity loads data , displays in recyclerview
  • the loading handled via singleton class

i test main activity follows

@rule public activitytestrule<mainactivity> mactivityrule = new activitytestrule<>(mainactivity.class);  @test public void testdataload() {     int poststotal = datasingleton.getinstance().getpostscount();     viewinteraction empty = onview(withid(r.id.empty_view));     viewinteraction recycler = onview(withid(r.id.recycler_view));     if (poststotal == 0) {         empty.check(matches(isdisplayed()));         recycler.check(matches(not(isdisplayed())));     } else {         empty.check(matches(not(isdisplayed())));         recycler.check(matches(isdisplayed()));         recycler.check(new recyclerviewitemcountassertion(greaterthan(poststotal)));     } } 

i know can't right way write tests. want able test both empty data set , non-empty set if-else 2 separate tests. way think can achieve mock data.

is there way? can use mockito make mainactivity use mock data without modifying production code? choice make inject either real or mocked data providers in place of singleton?

is better uninstall , reinstall app each time there no data start , continue real data testing?

android activity heavyweight , hard test. because don't have control on constructor, hard swap in test doubles.

the first thing make sure depending on abstraction of data-source rather concretion. if using singleton getpostscount() method extract interface:

interface datasourceabstraction {     int getpostscount(); } 

make wrapper class implements interface:

class concretedatasource implements datasourceabstraction {     @override     int getpostscount() {         return datasingleton.getinstance().getpostscount();     } } 

and make activity depend on rather concrete datasingleton

datasourceabstraction datasourceabstraction;  @override protected void oncreate(bundle savedinstancestate) {     super(savedinstancestate);     injectmembers(); }  @visiblefortesting void injectmembers() {     datasourceabstraction = new concretedatasource(); } 

you can swap in test double subclassing , overriding injectmembers has relaxed visibility. it's bad idea in enterprise development, there less options in android activities don't control constructor of class.

you can write:

datasourceabstraction datasource;  //system under test mainactivity mainactivity  @before public void setup() {     mockdatasource = mockito.mock(datasourceabstraction.class);     mainactivity = new mainactivity() {         @override         void injectmembers() {             datasourceabstraction = mockdatasource;         }     }; } 

Comments

Popular posts from this blog

php - Permission denied. Laravel linux server -

google bigquery - Delta between query execution time and Java query call to finish -

python - Pandas two dataframes multiplication? -