Shadows and Intents6:52 with Ben Deitch
In this video we'll introduce Shadow Classes, and finish up our testing with Robolectric!
It's time to finish up our Robolectric testing 0:00 by making sure that our launch activity button is working correctly. 0:02 Let's create a new test method at the bottom of the class and name it 0:06 buttonLaunchesOtherActivity. 0:12 And let's make sure it can throw an exception. 0:19 Then let's copy and paste in the arrange/act/assert comments and 0:27 get started arranging our test. 0:33 First, just like in main activity presenter test, 0:37 we'll need a class variable. 0:40 Class clazz = OtherActivity.class. 0:42 Next, in the act section, we need to click the button. 0:49 Let's type activity.launchActivityButton.callOnClick. 0:52 And finally for 1:02 the assert section, we just need to verify that we launched our other activity. 1:03 This is where things start to get a little bit tricky. 1:09 Remember, Robolectric isn't actually running our app. 1:12 So when we call the on click method of our launch activity button 1:16 It's not actually going to launch the other activity. 1:20 So instead of checking that we launched our other activity. 1:24 We'll just check that main activity calls start activity with the correct intent. 1:28 An easy way for us to do this with Robolectric is to use a Shadow Class. 1:34 A Shadow Class functions similarly to a mocked class, 1:40 like our mocked view we created earlier. 1:43 But behind the scenes, it's a little different. 1:46 When an Android framework class is first created, Robolectric looks for 1:49 a corresponding Shadow Class. 1:53 And if it finds one, it creates the corresponding shadow object. 1:56 Then, whenever a method is called on that framework class, 2:01 Robolectric first calls that method on the Shadow Class. 2:05 This way, the developers of Robolectric are able to capture 2:09 whatever is being called on the framework. 2:12 But, more importantly for us, it lets them add helpful methods to the shadow classes 2:15 to make testing less of a hassle. 2:20 One of these helpful methods from the Activity Shadow Class is called 2:22 getNextStartedActivity, which gives us null if there hasn't been a next activity, 2:26 or if there has it returns the intent of the next started activity. 2:33 Just what we're looking for. 2:38 So right below our assert comment, let's create a new ShadowActivity, 2:40 named shadowActivity. 2:47 And let's set it equal to Shadows.shadowOf and pass in our activity. 2:51 Alt+Enter to import shadows. 3:02 Then let's create a new Intent variable called actualIntent 3:05 and set it equal to, after importing the Intent class, 3:13 shadowActivity.getNextStartedActivity. 3:18 Now, we just need to create the expected intent, 3:24 which will do in the arrange section. 3:26 Intent, expected 3:28 intent and on second glance it looks like 3:35 this variable up here should probably be called actual color. 3:39 So let's change that real quick and 3:43 then back to our intent which equals a new intent and 3:51 we can pass in our activity for the context. 3:57 And then our clazz variable or the class. 4:02 And last but 4:06 not least, let's assert that the actual intent matches the expected intent. 4:07 assertEquals(expectedIntent, actualIntent), 4:11 nice. 4:21 Now let's comment out the act section so we can see the test fail. 4:22 Then let's right-click and run our test. 4:29 And just like we expected, it failed. 4:37 There was no next started activity, and we ended up with a null intent. 4:40 Now let's uncomment out the act section and run our test again. 4:45 And what? 5:00 It failed again? 5:02 If we look at the differences between these two Intents 5:03 they look basically the same, but 5:09 it does look like there might be an extra space on the left side here. 5:13 Either way here's what we need to know. 5:19 Intents can have small differences which can make two 5:21 seemingly identical Intents not actually equal to one another. 5:25 But using the filter equals method of the Intent class, 5:30 lets us ignore the small differences and instead 5:34 just tells us if the two Intents are equivalent from a functional standpoint. 5:37 Let's delete the assert statement and 5:42 rewrite it to instead make use of this filter equals method. 5:44 AssertTrue(expectedIntent.filterEquals(ac- tualIntent)). 5:52 Then let's run the test again. 6:02 And [LAUGH] there we go! 6:09 A passing test. 6:10 Finally let's right click somewhere at the top of the class and choose 6:12 run main activity test to run all 3 tests at once and 6:20 what do we get 3 passing test 6:25 Robolectric is a supremely cool way to test your Android apps. 6:30 It lets us write tests as if there's an actual device there 6:35 even though there's not but that's not always the best solution. 6:39 Sometimes you just can't get around using an actual device and the next stage. 6:43 We'll see how we can test the UI directly using espresso. 6:48
You need to sign up for Treehouse in order to download course files.Sign up