Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The activity should be set a component for testing, not the app #11

Open
stephanenicolas opened this issue Nov 5, 2015 · 5 comments
Open

Comments

@stephanenicolas
Copy link

It's too central the current way. In the activity, it scales up.

@chiuki
Copy link
Owner

chiuki commented Nov 5, 2015

Not sure what's the problem? Also how do you set the component in the activity before it starts its lifecycle i.e. onCreate?

@stephanenicolas
Copy link
Author

You got full control over it in your tests. Robolectric can build it and
give it back to you before you call onCreate, same for the ActivityTestRule in
Espresso.

The problem is that the app having the component of each activity would
make it ugly, if that is done at the activity level, then code is prettier
and the solution scales easily, without classes left out (open closed
principle).

S.

2015-11-05 9:23 GMT-08:00 Chiu-Ki Chan notifications@github.com:

Not sure what's the problem? Also how do you set the component in the
activity before it starts its lifecycle i.e. onCreate?


Reply to this email directly or view it on GitHub
#11 (comment)
.

@mdelolmo
Copy link

mdelolmo commented Oct 2, 2016

@stephanenicolas But this is an application scoped component, hence it should be the application the one that holds its reference.

@digitalbuddha
Copy link

Hi Stephane. I was lending a hand with this issue. I'm having trouble understanding what you mean. Are you saying that we should create the component in the activity? I'm having trouble figuring out what the issue is. Thanks and have a nice day

@stephanenicolas
Copy link
Author

stephanenicolas commented Nov 15, 2016

Hi Mike,

it's been such a while I wrote that comment ;)

But yeah, what I meant is that:

((DemoApplication) getApplication()).component().inject(this);

uses the app as a repository to get the component used for injection. It would be better to have the component used by the activity at the activity level. My comment was really about : if you have 20 activities, you are gonna create quite a lot of pollution in the app class to provide the components for all activities. I understand that @mdelolmo says it's an app component, but here it's not so clear I would say as the component is used unchanged by the activity. So it looks quite a lot like an activity component !

====start of parenthesis
Actually, and that is a bit different, when I re-read the example I also find it a bit awkward that the application knows about the activity: it knows about it transitively via the DemoComponent interface. I understand that this example is a toy but it gives the feeling of quite an un-layered wiring: things at the app level know about things at the activity level.

Let's think of it in term of the class loader: loading the app loads the app component then loads all sub components interfaces then loads all classes of all activities... This is not exactly ideal.

The approach you have in: http://fr.slideshare.net/nakhimovich/advanced-dagger-talk-from-360andev
slide 47 also has the same issue I would say: the plusing of the activity component in the app component also leads to this transgression of layers. Would it be possible to do it the other way around and have the activity component use the application component ?
=== end of parenthesis

I am not exactly sure about a better way to do things with dagger 2, but as Uncle Bob says all design problems have a single solution: introduce a new indirection layer ;) (I quite probably take shortcuts in his thoughts actually). Of course, this means that you want to use Dagger 2 during tests, which doesn't seem so recommended by the authors. By this I mean having a test for the activity that uses DI.

Here it would be interesting to have a new entity responsible for providing the component to the activity and you can replace this entity by a stub that will return a stub component during tests. Something like the component factory you use in your slides (48). Either a method of the activity returns this entity and you can test of subclass of your activity (bouhh) or you have a setter that you call in your tests when your activity has just been created to provide a fake component factory. This can be done at the instrumentation level during testing and be plugged in each test itself as you do it in your slides (67-69, 77-78).

It's 4-5 AM, not so sure I am clear and accurate on this ;)

Note: I find myself very good not even to have mentioned toothpick even once, I could as it doesn't have this kind of issues ... ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants