You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
Repository navigation
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
Improve testability by letting provide overrides for injected implementations #989
It would be nice to provide override implementations (e.g. mock instances) when using the builder to construct an enhanced component instance. Imagine a fragment where you want to inject a Tracking instance:
@EFragment(R.layout.tracked_fragment)
public class TrackedFragment extends Fragment {
@Bean
protected Tracking tracking;
@Override
public void onCreate(Bundle savedInstanceState) {
tracking.trackView();
}
}
In production code i would use this fragment like this:
fragment = TrackingFragment_.builder().build();
There will be a problem if you want to use it in a robolectric test like this:
public class TrackingFragmentTest {
private TrackingFragment fragment;
@Before
public void setUp() {
FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
fragment = TrackingFragment_.builder().build();
fragment.tracking = mock(Tracking.class); //option1
activity.getSupportFragmentManager().beginTransaction().add(fragment, null).commit();
fragment.tracking = mock(Tracking.class); //option2
}
}
Using option 1 doesn't do anything because the reference is overriden with a real Tracking instance by AA when the fragment transaction takes place. Option 2 leads to a call to trackView of the real Tracking instance because the call to onCreate() happens when the fragment transaction takes place - the manual injection happens to late.
A nice and elegant solution which offers enhanced injection capabilities would be to have something like a use, provide or override method in the builder:
Observing the same issue here, just forked the code and will try to provide a patch. Currently it is easy to test simple activities. As soon it gets more complex where is not really a good way to mock it.
I would suggest a full refactoring to a service locater pattern (e.g. like in Spring or Java EE) anyway the two major problems for mocks now are:
The extended Bean is final -- just removing the final would allow you to mock singleton beans by setting the instance_ via reflection
As already mentioned above setting beans etc. over package private accessors or setter wont work in more complex scenarios due to the lifecycle of some views
On the last point some more detail: As soon as you call getActivity in your test the whole thing starts and the mocks are sometimes not in the right state, you will see Nullpointers and other stuff.
Activity
sterlp commentedon May 10, 2016
Observing the same issue here, just forked the code and will try to provide a patch. Currently it is easy to test simple activities. As soon it gets more complex where is not really a good way to mock it.
I would suggest a full refactoring to a service locater pattern (e.g. like in Spring or Java EE) anyway the two major problems for mocks now are:
On the last point some more detail: As soon as you call getActivity in your test the whole thing starts and the mocks are sometimes not in the right state, you will see Nullpointers and other stuff.
sterlp commentedon May 10, 2016
Something like this should do the trick:
sterlp@4924378
My problem is that the project didn't compile at my machine - no idea why.
In addition you have to set generateFinalClasses to true: