jordifierro / android-base

Android Clean Architecture MVP RESTful client template app
http://jordifierro.com
83 stars 26 forks source link

How to test the presenter method in Fragment has been called? #10

Closed TonyTangAndroid closed 6 years ago

TonyTangAndroid commented 6 years ago

Hi there,

First of all, it has been amazing experience ever since I used this code base as an example to practice my clean architecture thought. It totally shifted my understanding of programming and software engineering. This is an amazing blueprint for the very clean architecture with nice and easy demo and test that could be easily understood.

Recently, I have been trying to shape my skill in unit test, which again, I use this code as example. While I do realize that the espresso test will cover the function that works in Fragment. As long as the expresso test is okay, it should be okay. But there is no way to verify whether or not the method from the presenter is called in fragment or not. For example, how would we verify that in BaseFragment.java the onResume() method has called the presenter's method resume(). This case might have been covered by Expresso Android Test. But there is no guarantee.

I have been trying to write the Fragment test case as Unit Test using Robolectric. But I was not able to find a proper. Any suggestion on how to address such issue? Or we do not need to address it as it could be covered by espresso Test.

@Override public void onResume() { super.onResume(); presenter().resume(); }

jordifierro commented 6 years ago

Hi @TonyTangAndroid! I'm really glad to hear that this repo helped you :)

About the resume() presenter method call, yes, you can test that easily, as we test the other interactions between fragment/activity and presenter. If you don't want to test that in every activity test (which is teadious) you can create a dummy presenter and fragment (under test folder) which inherit from BaseFragment and BasePresenter, and assert that resume() is called once fragment is loaded. You can use another dummy activity that loads your fragment or test it directly using a FragmentTestRule. Tell me if you have achieved it or if you have any doubts.

PD: I'm currently working on an Android project that is similar to this one but have some differences and interesting details that maybe can also help you, check it out here.

TonyTangAndroid commented 6 years ago

Hi @jordifierro Thank you for getting me back so quick and sharing me with your new project, which I believe that I would be able to learn a lot, specially in Kotlin related. Oh, man, you just always stay ahead of android development in all aspect.

Back to this topic, I am afraid that I feel a bit lost in implementing the following test cases.

you can create a dummy presenter and fragment (under test folder) which inherit from BaseFragment and BasePresenter, and assert that resume() is called once fragment is loaded

Here is my idea of steps to create this test case.

1, create the fragment in androidTest folder. 2, create a dummy presenter in androidTest folder. 3, add extra method only for test purpose to set the dummy presenter as the presenter in fragment. 4, call the fragment onResume method. 5, verify the dummy presenter's resume method has been called.

But I am not confident at all that it is viable. I have searched a lot of test example across the internet, so far I have not seen any related code that had demonstrated test case like this or try to achieve what I am doing. I have also just checked your new project and did not see the test case that is trying to verify the presenter method call in fragment or activity. I indeed see the presenter test cases and repository tests. But again, no fragment related test to verify the presenter method.

jordifierro commented 6 years ago

Your idea is fine. Step 4 can be skipped, just start the fragment and it should automatically call onResume() when loaded. Have you already tried it? Tell me if worked or not!

TonyTangAndroid commented 6 years ago

Hi Jordi, I get stuck at step 5. I could not verify the method has been called or not as the presenter is actually being created rather than mocked. And as far as I know, only mocked object could be verified against the method has been called or not.

While I do believe that there must be another way to verify whether the method has been called or not, I just could not come across such method as I have never seen such examples. Is there any known example that you have known of?

jordifierro commented 6 years ago

You have to create a MockModule (which will be used by TestMockerApplication) to inject mocked presenter. All view tests are done like that, you can check them as example. Also, in my block there is an step by step tutorial to do that.

TonyTangAndroid commented 6 years ago

Hello Jordi, I finally made it. I did not put enough attention on the androidTest under the presentation module. I did not realize that there had been actually the exact example that I had been looking for, which I felt a bit of shamed for bothering again.

TonyTangAndroid commented 6 years ago

I also did a few optimization to make the android-base project.

1, upgrade the android build tools version and the dependencies library and make corresponding changes to make the code compile and pass the test.

2, Introduced Dagger Android into this project, which could further more simplify the whole project.

I am going to send two pull request with corresponding comments.