Reputation: 4017
I'm working on a team project which has a very coupled code. I'm trying to increase the unit test coverage and I've faced the following scenario:
class Foo {
static void methodA () {
Bar b = new Bar();
b.getContent();
}
}
class Bar {
@Inject
DBAcessor mDBAcessor;
Bar () {
Dagger2.getInjector().inject(this);
}
public Object getContent() {
mDBAcessor.fetchData();
}
}
I want to unit test methodA()
, however I don't know if it is possible to do it without passing the DBAcessor
object via constructor to Bar()
class. Bar
should be a POJO model being widely used throughout the project, hence, I don't know if it would be a good idea to change its constructor and impact so many other classes. Any tips on how should I approach this scenario?
Upvotes: 0
Views: 1149
Reputation: 20268
That is wrong design.
Whenever you have an access to the constructor, pass class dependencies into constructor. That really eases unit testing. Class Bar
should look:
class Bar() {
@Inject DBAcessor mDBAcessor;
Bar (DBAcessor dbAcessor) {
this.mDBAcessor = dbAcessor;
}
public Object getContent() {
mDBAcessor.fetchData();
}
}
Dagger2
methods declared in Component
should only be used inside object you don't have an access to the constructor (Activity
or Fragment
).
Then nothing prevents you from doing that:
DBAccessor dbAccessor = Mockito.mock(DBAccessor.class);
Bar bar = new Bar(dbAccessor);
bar.getContent();
verify(bar, times(1)).fetchData();
If you really need to stick to such design, then you can't make unit tests on such object, as Dagger2
depends on Application
object, which needs Context
, which you cannot emulate in unit tests. Write your test as androidTest
, create appropriate Activity
, fetch Bar
object from it and test it.
Upvotes: 1