roboguice
DESCRIPTION
Dependency Injection & Inversion of Control for Android with RoboGuice. How to unit test Android project.TRANSCRIPT
![Page 1: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/1.jpg)
RoboGuiceDI & IoC framework for Android
![Page 2: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/2.jpg)
Me
Software Engineer @ FICO Corp.Programmer@nuboathttps://github.com/nuboathttp://slideshare.net/nuboat/
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 3: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/3.jpg)
RoboGuice
RoboGuice เป็น framework สาํหรับทาํ Dependency Injection บน Android, พัฒนาจาก Google Guice library. ลักษณะคลา้ยกับ Spring & EJB ของ JavaEE
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 4: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/4.jpg)
Normal Style
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 5: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/5.jpg)
RoboGuice Style
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 6: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/6.jpg)
Requirements
Java 6 or 7MavenAndroid SDK (platform 18)Coffee & Beer (up to you)
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 7: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/7.jpg)
Librarys
RoboGuice v3.0b-experimentalGoogle Guice v3.0Roboelectric v1.0Mockito v1.9.5JUnit v4.8.2
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 8: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/8.jpg)
Advantage of RoboGuice
Clean codeInherit Guice feature (Singleton, …)Automate TestingLog Framework
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 9: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/9.jpg)
Clean Code
RoboActivity not Activity
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 10: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/10.jpg)
Inheriting from the
RoboGuice
Inheriting from the
RoboGuice
Inheriting from the
RoboGuice
Inheriting from the
RoboGuice
Inheriting from the RoboGuice
RoboActivity
RoboListActivity
RoboExpandableListActivity
RoboMapActivity
RoboPreferenceActivity
RoboAccountAuthenticatorActivity
RoboActivityGroup
RoboTabActivity
RoboFragmentActivity
RoboLauncherActivity
RoboService
RoboIntentService
RoboFragment
RoboListFragment
RoboDialogFragment
etc.
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 11: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/11.jpg)
Inject ?
roboguice.inject.InjectViewroboguice.inject.InjectExtraroboguice.inject.InjectFragmentroboguice.inject.InjectPreferenceroboguice.inject.InjectResourcejavax.inject.Inject (POJO)
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 12: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/12.jpg)
@Singleton
public class Astroboy {
@Inject Application application;
@Inject Vibrator vibrator;
@Inject Random random;
public void say(final String something) {
// Make a Toast, using the current context as returned by the Context Provider
Toast.makeText(application, "Astroboy says, \"" + something + "\"", Toast.LENGTH_LONG).show();
}
public void brushTeeth() {
vibrator.vibrate(new long[]{0, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, }, -1);
}
public String punch() {
final String expletives[] = new String[]{"POW!", "BANG!", "KERPOW!", "OOF!"};
return expletives[random.nextInt(expletives.length)];
}
}
Singleton - Threadsafe
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 13: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/13.jpg)
Test Random value
@Singletonpublic class Astroboy {
public String punch() {
final String expletives[] = new String[]{"POW!", "BANG!", "KERPOW!", "OOF!"};
return expletives[random.nextInt(expletives.length)];
}
. . .}
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 14: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/14.jpg)
Test Code 1@RunWith(RobolectricTestRunner.class)
public class Astroboy1Test {
protected Context context = new RoboActivity();
protected Astroboy astroboy = RoboGuice.getInjector(context).getInstance(Astroboy.class);
@Test
public void stringShouldEndInExclamationMark() {
assertTrue(astroboy.punch().endsWith("!"));
}
}
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 15: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/15.jpg)
Test Vibrator@Singleton
public class Astroboy {
public void brushTeeth() {
vibrator.vibrate(
new long[]{0, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, }, -1);
}
. . .
}
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 16: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/16.jpg)
Test Code 2public class Astroboy2Test {
. . .
@Test
public void brushingTeethShouldCausePhoneToVibrate() {
// get the astroboy instance
final Astroboy astroboy = RoboGuice.getInjector(context).getInstance(Astroboy.class);
// do the thing
astroboy.brushTeeth();
// verify that by doing the thing, vibratorMock.vibrate was called
verify(vibratorMock).vibrate(new long[]{0, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50},-1);
}
}
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 17: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/17.jpg)
Test Code 2public class Astroboy2Test {
protected Application application = mock(Application.class, RETURNS_DEEP_STUBS);
protected Context context = mock(RoboActivity.class, RETURNS_DEEP_STUBS);
protected Vibrator vibratorMock = mock(Vibrator.class);
@Before
public void setup() {
// Override the default RoboGuice module
RoboGuice.setBaseApplicationInjector(application, RoboGuice.DEFAULT_STAGE,
Modules.override(RoboGuice.newDefaultRoboModule(application)).with(new MyTestModule()));
when(context.getApplicationContext()).thenReturn(application);
when(application.getApplicationContext()).thenReturn(application);
}
. . .
}
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 18: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/18.jpg)
Test Code 2public class Astroboy2Test {
. . .
public class MyTestModule extends AbstractModule {
@Override
protected void configure() {
bind(Vibrator.class).toInstance(vibratorMock);
}
}
}
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 19: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/19.jpg)
Test Code 2public class Astroboy2Test {
. . .
@After
public void teardown() {
// Don't forget to tear down our custom injector to avoid polluting other test classes
RoboGuice.util.reset();
}
}
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 20: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/20.jpg)
Log Framework
Log.d("TAG", "Sent say(" + something + ") command to Astroboy");
VS
Ln.d("Sent say(%s) command to Astroboy", something);
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 21: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/21.jpg)
Log Framework
public static int d(Object s1, Object[] args) {
...
}
Ln.d("Sent say(%s) command to Astroboy %s", something, “1”);
**it will automatically not log on a signed APK
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 22: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/22.jpg)
Short Workshop
ConfigBuildTestDeployRunDebug
![Page 23: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/23.jpg)
Maven - pom.xml #1
<properties>
<android.sdk.path>
C:\Program Files\adt-bundle-windows\sdk
</android.sdk.path>
</properties>
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 24: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/24.jpg)
Maven - pom.xml #1<!-- REGULAR DEPENDENCIES -->
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0</version>
<classifier>no_aop</classifier>
</dependency>
<dependency>
<groupId>org.roboguice</groupId>
<artifactId>roboguice</artifactId>
<version>3.0b-experimental</version>
</dependency>
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 25: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/25.jpg)
Maven - pom.xml #2<!-- TEST DEPENDENCIES -->
<dependency>
<groupId>com.pivotallabs</groupId>
<artifactId>robolectric</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 26: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/26.jpg)
Maven - pom.xml #3<!-- PROVIDED DEPENDENCIES -->
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>4.2.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>provided</scope>
</dependency>
<dependency> <!-- needed to prevent warnings in robolectric tests -->
<groupId>com.google.android.maps</groupId>
<artifactId>maps</artifactId>
<version>7_r1</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 27: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/27.jpg)
Maven - pom.xml #4<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile>
<assetsDirectory>${project.basedir}/assets</assetsDirectory>
<resourceDirectory>${project.basedir}/res</resourceDirectory>
<nativeLibrariesDirectory>${project.basedir}/src/main/native</nativeLibrariesDirectory>
<sdk>
<platform>18</platform>
</sdk>
<undeployBeforeDeploy>true</undeployBeforeDeploy>
</configuration>
<extensions>true</extensions>
</plugin>
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 28: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/28.jpg)
Maven - Command
mvn -DskipTests=true install
mvn test
mvn -DskipTests=true android:deploy
mvn -DskipTests=true android:run -Dandroid.run.debug=true
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 29: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/29.jpg)
NETBEANS
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 30: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/30.jpg)
Who uses RoboGuice?
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND
![Page 31: Roboguice](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f5f6ab4c9058a148b4677/html5/thumbnails/31.jpg)
THANK YOU
QUESTION
@ COPYRIGHT 2013 NUBOAT IN WONDERLAND