Join Chiu-Ki Chan for an in-depth discussion in this video Refactor: Show error, part of Effective Android Testing for Mobile Developers.
- [Instructor] In step three, we show an error when the recipe is null. Look at line 35, though. We don't know what is recipe anymore because we're hiding it inside the presenter. This is fine, because we will move this null check into the presenter. Copy line 36 to line 38. Switch to the presenter. Inside loadRecipe, in line 15, we are going to add the null check here.
If recipe equals null, we are going to paste in the line that we copied. And, actually, we don't need the return line, so we can delete that. Android Studio is not happy because it doesn't know what is the titleView and what is the descriptionView. This is fair, since they are TextView and Android-specific, and the presenter doesn't have a handle on it. To keep the presenter Java only, we will need to show error via the view interface. Open RecipeContract.
Inside the interface view, in line five, we will add the new function, void showRecipeNotFoundError. Then, we will switch back to the presenter, and instead of directly manipulating the title and the view, we are going to go through the view contract. Wait, we don't have a view contract in the presenter. That is all right. We're going to pass it in as parameter in the constructor in line 13.
Line 13, add a second parameter, comma, RecipeContract.View. We will call it view, and then we will add it as a field. So, after line 14, add this view equals view. Move the cursor to the red part, press Alt Enter to create a field. Now that we have a view, we can use it in load recipe. In line 22, call view.showRecipeNotFoundError.
Delete the lines that do not compile. Wait, recipe activity is not happy, we've got some rare squiggles. Let's go take a look. On top of the fact that in line 35, Recipe is not defined, now in line 31, the constructor to the presenter is also not good because we added a new parameter. We need to pass it a view. What is a view? Remember, view in MVP or model view presenter is not an Android view.
Rather, it's either an activity or a fragment. In our case, it's the recipe activity. So, in line 31, we will add this as the second parameter. This still not happy. Let's press Alt Enter to find out why. It is not happy because, currently, recipe activity is not a RecipeContract.view. What we are going to do here is we are going to have the activity implement that implement this interface.
This is the fourth option under this manual. Make recipe activity implement the contract. In the Select Methods to Implement dialog, keep the default, which is that we are going to implement showRecipeNotFoundError. Press OK. What are we going to do inside the showRecipeNotFoundError? If you look back at step three, that is exactly what we need to do. We need to copy and paste line 36 and 37 so that we are going to hide the titleView and then display the text RecipeNotFound in descriptionView.
Copy and paste, and now, titleView and descriptionView are not happy. Why? If we scroll back up, we can see that the titleView and the descriptionView are defined in lines 25 and 26 inside the onCreate function. Since we moved them out to a different function, we would also need to move these into fields. So what we're going to do is we're going to delete final TextView in line 25 and also delete TextView in line 26.
Then, press Alt Enter to create field for titleView and also descriptionView. Now, if we scroll down, in the function showRecipeNotFoundError in line 63, there is no more error. Scroll back up, and let's double check that we have taken care of step three. Step three says, if recipe is null, show error. If we jump into the loadRecipe call from line 34, we can see that, indeed, when the recipe is null, we will show RecipeNotFoundError.
Calling this function on the interface means that we are going to be actually calling the activity because the activity implements this interface, and in the activity implementation, it is doing what we were doing earlier, hiding the titleView and the descriptionView. In other words, we can delete line 37 through line 41. I'm going to just add into the comment just to make it clear.
So, step three, if recipe is null, show error. This is done in the presenter. That takes care of the case when the recipe is null. Next, we will look into step four, showing the recipe when it is not null.
- Why test?
- Local vs. on-device
- Code coverage
- UI testing
- Hermetic environment
- Dependency injection
- Testing with MVP