SlideShare a Scribd company logo
Guice
3/4/2014 1Guice - Evgeny Barabanov
Agenda
• Background
– Testability
– Dependency injection pattern (DI)
– Factory pattern
• Guice basics
• Unit testing with Guice and Mockito
• Best practices
• Useful links
3/4/2014 2Guice - Evgeny Barabanov
Testability
class A {
int complexCalculation(){
//Some calculation
}
}
class B {
A a;
B(){
a = new A();
}
int doubleCalculation{
return a.complexCalulation() * 2;
}
}
Why it is difficult to unit test class B?
3/4/2014 3Guice - Evgeny Barabanov
Testability
class A {
int complexCalculation(){
//Some calculation
}
}
class B {
A a;
B(){
a = new A();
}
int doubleCalculation{
return a.complexCalulation() * 2;
}
}
Why it is difficult to unit test class B?
What if
a.complexCalculation
computes wrong
result?
3/4/2014 4Guice - Evgeny Barabanov
Testability
Why it is difficult to unit test class B?
- B implementation depends directly on actual A implementation,
therefore we cannot test B as standalone class.
class A {
int complexCalculation(){
//Some calculation
}
}
class B {
A a;
B(){
a = new A();
}
int doubleCalculation{
return a.complexCalulation() * 2;
}
}
What if
a.complexCalculation
computes wrong
result?
3/4/2014 5Guice - Evgeny Barabanov
The solution – Dependency injection
interface IA {
int complexCalculation();
}
class A implements IA {
int complexCalculation(){
//Some calculation
}
}
class B {
IA a;
B(IA _a){
a = _a;
}
int doubleCalculation{
return a.complexCalculation() * 2;
}
}
Hollywood principle: “Don’t call us, we’ll call you”
3/4/2014 6Guice - Evgeny Barabanov
The solution – Dependency injection
interface IA {
int complexCalculation();
}
class A implements IA {
int complexCalculation(){
//Some calculation
}
}
class B {
IA a;
B(IA _a){
a = _a;
}
int doubleCalculation{
return a.complexCalculation() * 2;
}
}
Hollywood principle: “Don’t call us, we’ll call you”
Now A implementation is absolutely decoupled from B implementation…
3/4/2014 7Guice - Evgeny Barabanov
…It makes the unit testing of B much easier:
class AStub implements IA {
int complexCalculation(){
return 1;
}
}
class BTest(){
void testCalc(){
B b = new B(new AStub());
assert(b.doubleCalculation() == 2)
}
}
Now a.complexCalculation() may return wrong result and we don’t care,
because we’re only testing the pure functionality of B.
3/4/2014 8Guice - Evgeny Barabanov
But…
I’d like to order
a new computer
Sure! We’ll
ship it in few
hours!
3/4/2014 9Guice - Evgeny Barabanov
…There is a problem
WTF!!??
3/4/2014 10Guice - Evgeny Barabanov
class HardDrive implements IHardDrive {
HardDrive(IDiscCase c, IDiscPlatter p, ISpindle s, IActuator a ...){
//
}
///
}
class GraphicCard implements IGraphicCard {
GraphicCard(IGraphicMemory m, IHeatSink hs, IFun f ...){
//
}
//
}
class Computer implements IComputer {
Computer(IHardDrive hd, IGraphicCard gc, ....){
//
}
//
}
3/4/2014 11Guice - Evgeny Barabanov
class Homer {
IComputer homersPC;
Homer(){
IDiscCase c = new DiscCase();
IDiscPlatter p = new DiscPlatter();
ISpindle s = new Spindle();
IActuator a = new Actuator();
...
IHardDrive hd = new HardDrive(c,p,s,a,...);
IGraphicMemory m = new GraphicMemory();
IHeatSink hs = new HeatSink();
IFun f = new Fun();
...
IGraphicCard gc = new GraphicCard(m, hs, f, ...);
...
...
//And finally!!!
homersPC = new Computer(hd, gc, ... );
}
}
The amount of “new” grows exponentially!!!
3/4/2014 12Guice - Evgeny Barabanov
The solution - Factory
I’d like to order
a new computer
Sure! We’ll ship it
in few hours! And
we will assemble it
for you!
3/4/2014 13Guice - Evgeny Barabanov
WOW!!!
3/4/2014 14Guice - Evgeny Barabanov
class HardDriveFactory {
static IHardDrive GetHardDrive{
IDiscCase c = new DiscCase();
IDiscPlatter p = new DiscPlatter();
ISpindle s = new Spindle();
IActuator a = new Actuator();
...
return new HardDrive(c,p,s,a,...);
}
}
class GraphicCardFactory {
static IGraphicCard GetGraphicCard{
IGraphicMemory m = new GraphicMemory();
IHeatSink hs = new HeatSink();
IFun f = new Fun();
...
return new GraphicCard(m, hs, f, ...);
}
}
class ComputerFactory {
static IComputer GetComputer{
IHardDrive hd = HardDriveFactory.GetHardDrive();
IGraphicCard gc = GraphicCardFactory.GetGraphicCard();
...
return new Computer(hd, gc, ... );
}
}
class Homer {
IComputer homersPC;
Homer(){
homersPC = ComputerFactory.GetComputer();
}
}
3/4/2014 15Guice - Evgeny Barabanov
Factory
• Advantages:
– Single responsibility. There is a separate entity which is responsible for instantiation and
configuration of a concrete object.
– Decoupling. A factory class decouples the client and implementing class.
– Avoid code duplication. If, for example, we are changing the signature of A constructor, we don’t
have to go over all the classes which are using A, but just change it in A factory.
– Homer doesn’t have to assemble the computer by himself.
• Disadvantages:
– We still have tight coupling between Factory class and products.
– We still have testability issues with naive factory implementation (can be solved by using more
advanced factory techniques, like factory with reflection)
– We shall maintain additional classes
3/4/2014 16Guice - Evgeny Barabanov
The most powerful solution - Guice
Guice is a dependency injection framework, which
alleviates the need for factories and use of new in your
java code.
Your code will be easier to change, unit test and reuse in
other contexts.
Guice aims to make development and debugging easier
and faster, not harder and slower.
3/4/2014 17Guice - Evgeny Barabanov
With dependency injection, objects accept dependencies in their
constructors. To construct an object, you first build its
dependencies. But to build each dependency you
need its dependencies, and so on. So when you build an object, you
really need to build an object graph.
Building object graphs by hand (as you have seen) is labour
intensive, error prone, and makes testing difficult. Instead, Guice
can build the object graph for you. But first, Guice needs to be
configured to build the graph exactly as you want it.
Injector is Guice's object-graph builder. First we create the injector,
and then we can use that to build.
The most powerful solution - Guice
3/4/2014 18Guice - Evgeny Barabanov
Bindings
Guice uses bindings to map types to their
implementations.
3/4/2014 19Guice - Evgeny Barabanov
Explicit bindings
A module is a collection of bindings which is
passed to Injector on its creation.
In module we specify all the bindings we want
to be used in current context.
3/4/2014 20Guice - Evgeny Barabanov
Explicit bindings
Consider previous example with a computer (for simplicity let’s assume
that HardDrive and GraphicCard receive nothing in their constructors):
class HardDrive implements IHardDrive {
HardDrive(){
//
}
///
}
class GraphicCard implements IGraphicCard {
GraphicCard(){
//
}
//
}
class Computer implements IComputer {
Computer(IHardDrive hd, IGraphicCard gc, ....){
//
}
//
}
3/4/2014 21Guice - Evgeny Barabanov
Explicit bindings
Now lets define a module which will bind the
interfaces to their implementations:
public class ComputerModule extends AbstractModule {
@Override
protected void configure() {
/*
* This tells Guice that whenever it sees a dependency on a IHardDrive,
* it should satisfy the dependency using a HardDrive.
*/
bind(IHardDrive.class).to(HardDrive.class);
/*
* Similarly, this binding tells Guice that when IGraphicCard is used in
* a dependency, that should be satisfied with a GraphicCard.
*/
bind(IGraphicCard.class).to(GraphicCard.class);
/*
* Finally, this binding tells Guice that when IComputer is used in
* a dependency, that should be satisfied with a Computer.
*/
bind(IComputer.class).to(Computer.class);
}
3/4/2014 22Guice - Evgeny Barabanov
Explicit bindings
Once we defined a module and passed it to the injector,
Guice will be able to create all the dependencies for us.
class Homer {
static Injector injector = Guice.createInjector(new ComputerModule());
IComputer homersPC;
Homer(){
homerPC = injector.getInstance(IComputer.class);
}
}
3/4/2014 23Guice - Evgeny Barabanov
Implicit bindings
When the injector needs an instance of a type, it needs
a binding.
The bindings in a modules are called explicit bindings,
and the injector uses them whenever they're available.
If a type is needed but there isn't an explicit binding,
the injector will attempt to create a Just-In-Time
binding. These are also known as JIT bindings or
implicit bindings.
3/4/2014 24Guice - Evgeny Barabanov
Impicit bindings
Implicit binding is done by specifying @ImplementedBy
annotation on the interface. Thus, instead of creating a
module we can tell Guice what are default implicit
bindings for our interfaces:
@ImplementedBy(GraphicCard.class)
public interface IGraphicCard {
//
//...
//
}
@ImplementedBy(HardDrive.class)
public interface IHardDrive {
//
//...
//
}
@ImplementedBy(Computer.class)
public interface IComputer {
//
//...
//
}
3/4/2014 25Guice - Evgeny Barabanov
Bindings
There are much more bindings, we have only
seen the basic ones.
You can find out more about bindings here.
3/4/2014 26Guice - Evgeny Barabanov
Injections
It’s not enough to tell Guice what are the
bindings. We also need to tell him what are
injected objects for each class.
There are several ways to do that, let’s look at
couple of them.
3/4/2014 27Guice - Evgeny Barabanov
Constructor injection
Constructor injection combines instantiation with injection. To use it, we
should annotate the constructor with the @Inject annotation. This
constructor should accept class dependencies as parameters. Most
constructors will then assign the parameters to fields (better final fields).
public class Computer implements IComputer{
final IHardDrive m_hd;
IGraphicCard m_gc;
@Inject
public Computer(IHardDrive hd, IGraphicCard gc){
m_hd = hd;
m_gc = gc;
}
}
If your class has no @Inject-annotated constructor, Guice will use a
public, no-arguments constructor if it exists.
Constructor injection works nicely with unit testing. If your class accepts
all of its dependencies in a single constructor, you won't accidentally
forget to set a dependency
3/4/2014 28Guice - Evgeny Barabanov
Field injection
Guice injects fields with the @Inject annotation. This is the most concise
injection, but the least testable.
public class Homer {
@Inject
private IComputer m_comp;
}
public class Main {
public static void main(String [] args)
{
Injector injector = Guice.createInjector();
Homer homer = injector.getInstance(Homer.class);
}
}
At the end of “main” method Homer will have an instance of Computer
with all its subcomponents.
3/4/2014 29Guice - Evgeny Barabanov
Injections
You can find out more about Injections here.
3/4/2014 30Guice - Evgeny Barabanov
Unit testing with Guice and Mockito
We want to unit test Computer, so we don’t want to be dependent on
GraphicCard and HardDrive implementations. The only thing we want
to test is a Computers functionality.
Guice provides us great ability to change binding.
All we need is just define two stubs (for GraphicCard and HardDrive),
define a new module which will bind interfaces to these stubs and
pass this module to the injector in test module.
But are we really want to maintain stub classes? Absolutely – NO.
Mockito provides us great ability to simulate classes behavior with its
Mocks, but as Mock is not a user defined class, we cannot bind
interface to the Mock.
So how can we combine and use both of these great frameworks?
3/4/2014 31Guice - Evgeny Barabanov
Unit testing with Guice and Mockito
The solution is @Provides methods:
@Provides method allows us to create an object when the object requires
additional code to be created, set up or configured . The method must be
defined within a module, and it must have an @Provides annotation. The
method's return type is the bound type. Whenever the injector needs an
instance of that type, it will invoke the method.
Guice does not allow exceptions to be thrown from Providers. Exceptions
thrown by @Provides methods will be wrapped in a ProvisionException. It is
bad practice to allow any kind of exception to be thrown -- runtime or
checked -- from an @Provides method.
3/4/2014 32Guice - Evgeny Barabanov
Unit testing with Guice and Mockito
Consider previous example with computer:
public class HardDrive implements IHardDrive {
@Override
public int CalculateSpeed() {
int result = 0;
//Complicated and long computation
return result;
}
}
public class GraphicCard implements IGraphicCard {
@Override
public int GetPerformanceRate() {
int result = 0;
//Complicated and long computation
return result;
}
}
public class Computer implements IComputer{
IHardDrive m_hd;
IGraphicCard m_gc;
@Inject
public Computer(IHardDrive hd, IGraphicCard gc){
m_hd = hd;
m_gc = gc;
}
@Override
public int GetComputerPerformanceRate() {
return m_hd.CalculateSpeed()+m_gc.GetPerformanceRate();
}
}
3/4/2014 33Guice - Evgeny Barabanov
Unit testing with Guice and Mockito
We’d like to test GetComputerPerformanceRate method.
So lets do that!
First, we create a module which defines @Provides methods
for GraphicCard and HardDrive stubs:
public class ComputerTestsModule extends AbstractModule {
@Override
protected void configure() {
}
@Provides
IHardDrive provideHardDrive(){
IHardDrive hd = mock(IHardDrive.class);
when(hd.CalculateSpeed()).thenReturn(5);
return hd;
}
@Provides
IGraphicCard provideGraphicCard(){
IGraphicCard gc = mock(IGraphicCard.class);
when(gc.GetPerformanceRate()).thenReturn(10);
return gc;
}
}
3/4/2014 34Guice - Evgeny Barabanov
Unit testing with Guice and Mockito
After we tell Guice to use our module instead of default binding
for HardDrive and GraphicCard creation, we can unit test the desired class:
public class ComputerTests extends TestCase {
static Injector injector = Guice.createInjector(new ComputerTestsModule());
IComputer cpForTest = injector.getInstance(IComputer.class);
@Test
public void testComputerPerformance(){
assertEquals(15, cpForTest.GetComputerPerformanceRate());
}
}
3/4/2014 35Guice - Evgeny Barabanov
Best practices
• Minimize mutability
• Inject only direct dependencies
• Avoid cyclic dependencies
• Avoid static state
• Use @Nullable
• Create fast and side-effects free modules
• Be careful about I/O in providers
• Avoid conditional logic in modules
• Keep constructors as hidden as possible
3/4/2014 36Guice - Evgeny Barabanov
Useful links
• FAQ
• Using Guice with Google AppEngine
3/4/2014 37Guice - Evgeny Barabanov

More Related Content

Viewers also liked

Google Guice presentation at Montreal JUG - October 2010
Google Guice presentation at Montreal JUG - October 2010Google Guice presentation at Montreal JUG - October 2010
Google Guice presentation at Montreal JUG - October 2010Mathieu Carbou
 
Introduction to Google Guice
Introduction to Google GuiceIntroduction to Google Guice
Introduction to Google Guice
Knoldus Inc.
 
What is exactly anti fragile in dev ops - v3
What is exactly anti fragile in dev ops - v3What is exactly anti fragile in dev ops - v3
What is exactly anti fragile in dev ops - v3Asher Sterkin
 
Google Guice
Google GuiceGoogle Guice
Google Guice
Andriy Andrunevchyn
 
Scala does the Catwalk
Scala does the CatwalkScala does the Catwalk
Scala does the Catwalk
Ariel Kogan
 
Orchestration tool roundup - OpenStack Israel summit - kubernetes vs. docker...
Orchestration tool roundup  - OpenStack Israel summit - kubernetes vs. docker...Orchestration tool roundup  - OpenStack Israel summit - kubernetes vs. docker...
Orchestration tool roundup - OpenStack Israel summit - kubernetes vs. docker...
Uri Cohen
 
JavaScript TDD
JavaScript TDDJavaScript TDD
JavaScript TDD
Uri Lavi
 
Elasticsearch na prática
Elasticsearch na práticaElasticsearch na prática
Elasticsearch na prática
Breno Oliveira
 
HagayOnn_EnglishCV_ 2016
HagayOnn_EnglishCV_ 2016HagayOnn_EnglishCV_ 2016
HagayOnn_EnglishCV_ 2016
Hagay Onn (the Spot)
 
Not your dad's h base new
Not your dad's h base newNot your dad's h base new
Not your dad's h base new
Yaniv Rodenski
 
What's the Magic in LinkedIn?
What's the Magic in LinkedIn?What's the Magic in LinkedIn?
What's the Magic in LinkedIn?
Efrat Fenigson
 
Scrum. software engineering seminar
Scrum. software engineering seminarScrum. software engineering seminar
Scrum. software engineering seminar
Alexandr Gavrishev
 
Storm at Forter
Storm at ForterStorm at Forter
Storm at Forter
Re'em Bensimhon
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
Maxim Novak
 
Code quality as a built-in process
Code quality as a built-in processCode quality as a built-in process
Code quality as a built-in process
Elad Maimon
 
How does the Internet Work?
How does the Internet Work?How does the Internet Work?
How does the Internet Work?
Dina Goldshtein
 
Lessons Learned with Unity and WebGL
Lessons Learned with Unity and WebGLLessons Learned with Unity and WebGL
Lessons Learned with Unity and WebGL
Lior Tal
 
How fast ist it really? Benchmarking in practice
How fast ist it really? Benchmarking in practiceHow fast ist it really? Benchmarking in practice
How fast ist it really? Benchmarking in practice
Tobias Pfeiffer
 
Continuous Deployment into the Unknown with Artifactory, Bintray, Docker and ...
Continuous Deployment into the Unknown with Artifactory, Bintray, Docker and ...Continuous Deployment into the Unknown with Artifactory, Bintray, Docker and ...
Continuous Deployment into the Unknown with Artifactory, Bintray, Docker and ...
Gilad Garon
 
Optimizing DevOps strategy in a large enterprise
Optimizing DevOps strategy in a large enterpriseOptimizing DevOps strategy in a large enterprise
Optimizing DevOps strategy in a large enterprise
Eyal Edri
 

Viewers also liked (20)

Google Guice presentation at Montreal JUG - October 2010
Google Guice presentation at Montreal JUG - October 2010Google Guice presentation at Montreal JUG - October 2010
Google Guice presentation at Montreal JUG - October 2010
 
Introduction to Google Guice
Introduction to Google GuiceIntroduction to Google Guice
Introduction to Google Guice
 
What is exactly anti fragile in dev ops - v3
What is exactly anti fragile in dev ops - v3What is exactly anti fragile in dev ops - v3
What is exactly anti fragile in dev ops - v3
 
Google Guice
Google GuiceGoogle Guice
Google Guice
 
Scala does the Catwalk
Scala does the CatwalkScala does the Catwalk
Scala does the Catwalk
 
Orchestration tool roundup - OpenStack Israel summit - kubernetes vs. docker...
Orchestration tool roundup  - OpenStack Israel summit - kubernetes vs. docker...Orchestration tool roundup  - OpenStack Israel summit - kubernetes vs. docker...
Orchestration tool roundup - OpenStack Israel summit - kubernetes vs. docker...
 
JavaScript TDD
JavaScript TDDJavaScript TDD
JavaScript TDD
 
Elasticsearch na prática
Elasticsearch na práticaElasticsearch na prática
Elasticsearch na prática
 
HagayOnn_EnglishCV_ 2016
HagayOnn_EnglishCV_ 2016HagayOnn_EnglishCV_ 2016
HagayOnn_EnglishCV_ 2016
 
Not your dad's h base new
Not your dad's h base newNot your dad's h base new
Not your dad's h base new
 
What's the Magic in LinkedIn?
What's the Magic in LinkedIn?What's the Magic in LinkedIn?
What's the Magic in LinkedIn?
 
Scrum. software engineering seminar
Scrum. software engineering seminarScrum. software engineering seminar
Scrum. software engineering seminar
 
Storm at Forter
Storm at ForterStorm at Forter
Storm at Forter
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Code quality as a built-in process
Code quality as a built-in processCode quality as a built-in process
Code quality as a built-in process
 
How does the Internet Work?
How does the Internet Work?How does the Internet Work?
How does the Internet Work?
 
Lessons Learned with Unity and WebGL
Lessons Learned with Unity and WebGLLessons Learned with Unity and WebGL
Lessons Learned with Unity and WebGL
 
How fast ist it really? Benchmarking in practice
How fast ist it really? Benchmarking in practiceHow fast ist it really? Benchmarking in practice
How fast ist it really? Benchmarking in practice
 
Continuous Deployment into the Unknown with Artifactory, Bintray, Docker and ...
Continuous Deployment into the Unknown with Artifactory, Bintray, Docker and ...Continuous Deployment into the Unknown with Artifactory, Bintray, Docker and ...
Continuous Deployment into the Unknown with Artifactory, Bintray, Docker and ...
 
Optimizing DevOps strategy in a large enterprise
Optimizing DevOps strategy in a large enterpriseOptimizing DevOps strategy in a large enterprise
Optimizing DevOps strategy in a large enterprise
 

Similar to Guice - dependency injection framework

FuzzyDebugger.pdf
FuzzyDebugger.pdfFuzzyDebugger.pdf
FuzzyDebugger.pdf
ritviktanksalkar1
 
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Christian Catalan
 
PRG/215 ENTIRE CLASS UOP TUTORIALS
PRG/215 ENTIRE CLASS UOP TUTORIALSPRG/215 ENTIRE CLASS UOP TUTORIALS
PRG/215 ENTIRE CLASS UOP TUTORIALS
Sharon Reynolds
 
GR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul KingGR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf
 
Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19
José Paumard
 
F3-DP-2015-Milata-Tomas-java-ee-batch-editor (1)
F3-DP-2015-Milata-Tomas-java-ee-batch-editor (1)F3-DP-2015-Milata-Tomas-java-ee-batch-editor (1)
F3-DP-2015-Milata-Tomas-java-ee-batch-editor (1)Tomáš Milata
 
Integration testing - A&BP CC
Integration testing - A&BP CCIntegration testing - A&BP CC
Integration testing - A&BP CC
JWORKS powered by Ordina
 
Advanced Road Design with InfraWorks
Advanced Road Design with InfraWorksAdvanced Road Design with InfraWorks
Advanced Road Design with InfraWorks
Quentin Marquette
 
PHP Unit Testing in Yii
PHP Unit Testing in YiiPHP Unit Testing in Yii
PHP Unit Testing in Yii
IlPeach
 
Izumi 1.0: Your Next Scala Stack
Izumi 1.0: Your Next Scala StackIzumi 1.0: Your Next Scala Stack
Izumi 1.0: Your Next Scala Stack
7mind
 
Why Gradle?
Why Gradle?Why Gradle?
Why Gradle?
Peter Ledbrook
 
Java bad coding practices
Java bad coding practicesJava bad coding practices
Java bad coding practices
Gustavo Carrion, MiT
 
As074lsg
As074lsgAs074lsg
As074lsg
Javalog Systems
 
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie..."How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
Fwdays
 
Griffon Presentation
Griffon PresentationGriffon Presentation
Griffon Presentation
Kelly Robinson
 
Greach 2015 Spock workshop
Greach 2015 Spock workshopGreach 2015 Spock workshop
Greach 2015 Spock workshop
Fernando Redondo Ramírez
 
BIT211.pdf
BIT211.pdfBIT211.pdf
BIT211.pdf
Sameer607695
 
Hadoop: Big Data Stacks validation w/ iTest How to tame the elephant?
Hadoop:  Big Data Stacks validation w/ iTest  How to tame the elephant?Hadoop:  Big Data Stacks validation w/ iTest  How to tame the elephant?
Hadoop: Big Data Stacks validation w/ iTest How to tame the elephant?
Dmitri Shiryaev
 
Bci for Beginners
Bci for BeginnersBci for Beginners
Bci for Beginners
IainLewis
 
CoC NA 2023 - Reproducible Builds for the JVM and beyond.pptx
CoC NA 2023 - Reproducible Builds for the JVM and beyond.pptxCoC NA 2023 - Reproducible Builds for the JVM and beyond.pptx
CoC NA 2023 - Reproducible Builds for the JVM and beyond.pptx
Hervé Boutemy
 

Similar to Guice - dependency injection framework (20)

FuzzyDebugger.pdf
FuzzyDebugger.pdfFuzzyDebugger.pdf
FuzzyDebugger.pdf
 
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
 
PRG/215 ENTIRE CLASS UOP TUTORIALS
PRG/215 ENTIRE CLASS UOP TUTORIALSPRG/215 ENTIRE CLASS UOP TUTORIALS
PRG/215 ENTIRE CLASS UOP TUTORIALS
 
GR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul KingGR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul King
 
Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19
 
F3-DP-2015-Milata-Tomas-java-ee-batch-editor (1)
F3-DP-2015-Milata-Tomas-java-ee-batch-editor (1)F3-DP-2015-Milata-Tomas-java-ee-batch-editor (1)
F3-DP-2015-Milata-Tomas-java-ee-batch-editor (1)
 
Integration testing - A&BP CC
Integration testing - A&BP CCIntegration testing - A&BP CC
Integration testing - A&BP CC
 
Advanced Road Design with InfraWorks
Advanced Road Design with InfraWorksAdvanced Road Design with InfraWorks
Advanced Road Design with InfraWorks
 
PHP Unit Testing in Yii
PHP Unit Testing in YiiPHP Unit Testing in Yii
PHP Unit Testing in Yii
 
Izumi 1.0: Your Next Scala Stack
Izumi 1.0: Your Next Scala StackIzumi 1.0: Your Next Scala Stack
Izumi 1.0: Your Next Scala Stack
 
Why Gradle?
Why Gradle?Why Gradle?
Why Gradle?
 
Java bad coding practices
Java bad coding practicesJava bad coding practices
Java bad coding practices
 
As074lsg
As074lsgAs074lsg
As074lsg
 
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie..."How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
 
Griffon Presentation
Griffon PresentationGriffon Presentation
Griffon Presentation
 
Greach 2015 Spock workshop
Greach 2015 Spock workshopGreach 2015 Spock workshop
Greach 2015 Spock workshop
 
BIT211.pdf
BIT211.pdfBIT211.pdf
BIT211.pdf
 
Hadoop: Big Data Stacks validation w/ iTest How to tame the elephant?
Hadoop:  Big Data Stacks validation w/ iTest  How to tame the elephant?Hadoop:  Big Data Stacks validation w/ iTest  How to tame the elephant?
Hadoop: Big Data Stacks validation w/ iTest How to tame the elephant?
 
Bci for Beginners
Bci for BeginnersBci for Beginners
Bci for Beginners
 
CoC NA 2023 - Reproducible Builds for the JVM and beyond.pptx
CoC NA 2023 - Reproducible Builds for the JVM and beyond.pptxCoC NA 2023 - Reproducible Builds for the JVM and beyond.pptx
CoC NA 2023 - Reproducible Builds for the JVM and beyond.pptx
 

Recently uploaded

Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
ShamsuddeenMuhammadA
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
XfilesPro
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
abdulrafaychaudhry
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 

Recently uploaded (20)

Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 

Guice - dependency injection framework

  • 1. Guice 3/4/2014 1Guice - Evgeny Barabanov
  • 2. Agenda • Background – Testability – Dependency injection pattern (DI) – Factory pattern • Guice basics • Unit testing with Guice and Mockito • Best practices • Useful links 3/4/2014 2Guice - Evgeny Barabanov
  • 3. Testability class A { int complexCalculation(){ //Some calculation } } class B { A a; B(){ a = new A(); } int doubleCalculation{ return a.complexCalulation() * 2; } } Why it is difficult to unit test class B? 3/4/2014 3Guice - Evgeny Barabanov
  • 4. Testability class A { int complexCalculation(){ //Some calculation } } class B { A a; B(){ a = new A(); } int doubleCalculation{ return a.complexCalulation() * 2; } } Why it is difficult to unit test class B? What if a.complexCalculation computes wrong result? 3/4/2014 4Guice - Evgeny Barabanov
  • 5. Testability Why it is difficult to unit test class B? - B implementation depends directly on actual A implementation, therefore we cannot test B as standalone class. class A { int complexCalculation(){ //Some calculation } } class B { A a; B(){ a = new A(); } int doubleCalculation{ return a.complexCalulation() * 2; } } What if a.complexCalculation computes wrong result? 3/4/2014 5Guice - Evgeny Barabanov
  • 6. The solution – Dependency injection interface IA { int complexCalculation(); } class A implements IA { int complexCalculation(){ //Some calculation } } class B { IA a; B(IA _a){ a = _a; } int doubleCalculation{ return a.complexCalculation() * 2; } } Hollywood principle: “Don’t call us, we’ll call you” 3/4/2014 6Guice - Evgeny Barabanov
  • 7. The solution – Dependency injection interface IA { int complexCalculation(); } class A implements IA { int complexCalculation(){ //Some calculation } } class B { IA a; B(IA _a){ a = _a; } int doubleCalculation{ return a.complexCalculation() * 2; } } Hollywood principle: “Don’t call us, we’ll call you” Now A implementation is absolutely decoupled from B implementation… 3/4/2014 7Guice - Evgeny Barabanov
  • 8. …It makes the unit testing of B much easier: class AStub implements IA { int complexCalculation(){ return 1; } } class BTest(){ void testCalc(){ B b = new B(new AStub()); assert(b.doubleCalculation() == 2) } } Now a.complexCalculation() may return wrong result and we don’t care, because we’re only testing the pure functionality of B. 3/4/2014 8Guice - Evgeny Barabanov
  • 9. But… I’d like to order a new computer Sure! We’ll ship it in few hours! 3/4/2014 9Guice - Evgeny Barabanov
  • 10. …There is a problem WTF!!?? 3/4/2014 10Guice - Evgeny Barabanov
  • 11. class HardDrive implements IHardDrive { HardDrive(IDiscCase c, IDiscPlatter p, ISpindle s, IActuator a ...){ // } /// } class GraphicCard implements IGraphicCard { GraphicCard(IGraphicMemory m, IHeatSink hs, IFun f ...){ // } // } class Computer implements IComputer { Computer(IHardDrive hd, IGraphicCard gc, ....){ // } // } 3/4/2014 11Guice - Evgeny Barabanov
  • 12. class Homer { IComputer homersPC; Homer(){ IDiscCase c = new DiscCase(); IDiscPlatter p = new DiscPlatter(); ISpindle s = new Spindle(); IActuator a = new Actuator(); ... IHardDrive hd = new HardDrive(c,p,s,a,...); IGraphicMemory m = new GraphicMemory(); IHeatSink hs = new HeatSink(); IFun f = new Fun(); ... IGraphicCard gc = new GraphicCard(m, hs, f, ...); ... ... //And finally!!! homersPC = new Computer(hd, gc, ... ); } } The amount of “new” grows exponentially!!! 3/4/2014 12Guice - Evgeny Barabanov
  • 13. The solution - Factory I’d like to order a new computer Sure! We’ll ship it in few hours! And we will assemble it for you! 3/4/2014 13Guice - Evgeny Barabanov
  • 14. WOW!!! 3/4/2014 14Guice - Evgeny Barabanov
  • 15. class HardDriveFactory { static IHardDrive GetHardDrive{ IDiscCase c = new DiscCase(); IDiscPlatter p = new DiscPlatter(); ISpindle s = new Spindle(); IActuator a = new Actuator(); ... return new HardDrive(c,p,s,a,...); } } class GraphicCardFactory { static IGraphicCard GetGraphicCard{ IGraphicMemory m = new GraphicMemory(); IHeatSink hs = new HeatSink(); IFun f = new Fun(); ... return new GraphicCard(m, hs, f, ...); } } class ComputerFactory { static IComputer GetComputer{ IHardDrive hd = HardDriveFactory.GetHardDrive(); IGraphicCard gc = GraphicCardFactory.GetGraphicCard(); ... return new Computer(hd, gc, ... ); } } class Homer { IComputer homersPC; Homer(){ homersPC = ComputerFactory.GetComputer(); } } 3/4/2014 15Guice - Evgeny Barabanov
  • 16. Factory • Advantages: – Single responsibility. There is a separate entity which is responsible for instantiation and configuration of a concrete object. – Decoupling. A factory class decouples the client and implementing class. – Avoid code duplication. If, for example, we are changing the signature of A constructor, we don’t have to go over all the classes which are using A, but just change it in A factory. – Homer doesn’t have to assemble the computer by himself. • Disadvantages: – We still have tight coupling between Factory class and products. – We still have testability issues with naive factory implementation (can be solved by using more advanced factory techniques, like factory with reflection) – We shall maintain additional classes 3/4/2014 16Guice - Evgeny Barabanov
  • 17. The most powerful solution - Guice Guice is a dependency injection framework, which alleviates the need for factories and use of new in your java code. Your code will be easier to change, unit test and reuse in other contexts. Guice aims to make development and debugging easier and faster, not harder and slower. 3/4/2014 17Guice - Evgeny Barabanov
  • 18. With dependency injection, objects accept dependencies in their constructors. To construct an object, you first build its dependencies. But to build each dependency you need its dependencies, and so on. So when you build an object, you really need to build an object graph. Building object graphs by hand (as you have seen) is labour intensive, error prone, and makes testing difficult. Instead, Guice can build the object graph for you. But first, Guice needs to be configured to build the graph exactly as you want it. Injector is Guice's object-graph builder. First we create the injector, and then we can use that to build. The most powerful solution - Guice 3/4/2014 18Guice - Evgeny Barabanov
  • 19. Bindings Guice uses bindings to map types to their implementations. 3/4/2014 19Guice - Evgeny Barabanov
  • 20. Explicit bindings A module is a collection of bindings which is passed to Injector on its creation. In module we specify all the bindings we want to be used in current context. 3/4/2014 20Guice - Evgeny Barabanov
  • 21. Explicit bindings Consider previous example with a computer (for simplicity let’s assume that HardDrive and GraphicCard receive nothing in their constructors): class HardDrive implements IHardDrive { HardDrive(){ // } /// } class GraphicCard implements IGraphicCard { GraphicCard(){ // } // } class Computer implements IComputer { Computer(IHardDrive hd, IGraphicCard gc, ....){ // } // } 3/4/2014 21Guice - Evgeny Barabanov
  • 22. Explicit bindings Now lets define a module which will bind the interfaces to their implementations: public class ComputerModule extends AbstractModule { @Override protected void configure() { /* * This tells Guice that whenever it sees a dependency on a IHardDrive, * it should satisfy the dependency using a HardDrive. */ bind(IHardDrive.class).to(HardDrive.class); /* * Similarly, this binding tells Guice that when IGraphicCard is used in * a dependency, that should be satisfied with a GraphicCard. */ bind(IGraphicCard.class).to(GraphicCard.class); /* * Finally, this binding tells Guice that when IComputer is used in * a dependency, that should be satisfied with a Computer. */ bind(IComputer.class).to(Computer.class); } 3/4/2014 22Guice - Evgeny Barabanov
  • 23. Explicit bindings Once we defined a module and passed it to the injector, Guice will be able to create all the dependencies for us. class Homer { static Injector injector = Guice.createInjector(new ComputerModule()); IComputer homersPC; Homer(){ homerPC = injector.getInstance(IComputer.class); } } 3/4/2014 23Guice - Evgeny Barabanov
  • 24. Implicit bindings When the injector needs an instance of a type, it needs a binding. The bindings in a modules are called explicit bindings, and the injector uses them whenever they're available. If a type is needed but there isn't an explicit binding, the injector will attempt to create a Just-In-Time binding. These are also known as JIT bindings or implicit bindings. 3/4/2014 24Guice - Evgeny Barabanov
  • 25. Impicit bindings Implicit binding is done by specifying @ImplementedBy annotation on the interface. Thus, instead of creating a module we can tell Guice what are default implicit bindings for our interfaces: @ImplementedBy(GraphicCard.class) public interface IGraphicCard { // //... // } @ImplementedBy(HardDrive.class) public interface IHardDrive { // //... // } @ImplementedBy(Computer.class) public interface IComputer { // //... // } 3/4/2014 25Guice - Evgeny Barabanov
  • 26. Bindings There are much more bindings, we have only seen the basic ones. You can find out more about bindings here. 3/4/2014 26Guice - Evgeny Barabanov
  • 27. Injections It’s not enough to tell Guice what are the bindings. We also need to tell him what are injected objects for each class. There are several ways to do that, let’s look at couple of them. 3/4/2014 27Guice - Evgeny Barabanov
  • 28. Constructor injection Constructor injection combines instantiation with injection. To use it, we should annotate the constructor with the @Inject annotation. This constructor should accept class dependencies as parameters. Most constructors will then assign the parameters to fields (better final fields). public class Computer implements IComputer{ final IHardDrive m_hd; IGraphicCard m_gc; @Inject public Computer(IHardDrive hd, IGraphicCard gc){ m_hd = hd; m_gc = gc; } } If your class has no @Inject-annotated constructor, Guice will use a public, no-arguments constructor if it exists. Constructor injection works nicely with unit testing. If your class accepts all of its dependencies in a single constructor, you won't accidentally forget to set a dependency 3/4/2014 28Guice - Evgeny Barabanov
  • 29. Field injection Guice injects fields with the @Inject annotation. This is the most concise injection, but the least testable. public class Homer { @Inject private IComputer m_comp; } public class Main { public static void main(String [] args) { Injector injector = Guice.createInjector(); Homer homer = injector.getInstance(Homer.class); } } At the end of “main” method Homer will have an instance of Computer with all its subcomponents. 3/4/2014 29Guice - Evgeny Barabanov
  • 30. Injections You can find out more about Injections here. 3/4/2014 30Guice - Evgeny Barabanov
  • 31. Unit testing with Guice and Mockito We want to unit test Computer, so we don’t want to be dependent on GraphicCard and HardDrive implementations. The only thing we want to test is a Computers functionality. Guice provides us great ability to change binding. All we need is just define two stubs (for GraphicCard and HardDrive), define a new module which will bind interfaces to these stubs and pass this module to the injector in test module. But are we really want to maintain stub classes? Absolutely – NO. Mockito provides us great ability to simulate classes behavior with its Mocks, but as Mock is not a user defined class, we cannot bind interface to the Mock. So how can we combine and use both of these great frameworks? 3/4/2014 31Guice - Evgeny Barabanov
  • 32. Unit testing with Guice and Mockito The solution is @Provides methods: @Provides method allows us to create an object when the object requires additional code to be created, set up or configured . The method must be defined within a module, and it must have an @Provides annotation. The method's return type is the bound type. Whenever the injector needs an instance of that type, it will invoke the method. Guice does not allow exceptions to be thrown from Providers. Exceptions thrown by @Provides methods will be wrapped in a ProvisionException. It is bad practice to allow any kind of exception to be thrown -- runtime or checked -- from an @Provides method. 3/4/2014 32Guice - Evgeny Barabanov
  • 33. Unit testing with Guice and Mockito Consider previous example with computer: public class HardDrive implements IHardDrive { @Override public int CalculateSpeed() { int result = 0; //Complicated and long computation return result; } } public class GraphicCard implements IGraphicCard { @Override public int GetPerformanceRate() { int result = 0; //Complicated and long computation return result; } } public class Computer implements IComputer{ IHardDrive m_hd; IGraphicCard m_gc; @Inject public Computer(IHardDrive hd, IGraphicCard gc){ m_hd = hd; m_gc = gc; } @Override public int GetComputerPerformanceRate() { return m_hd.CalculateSpeed()+m_gc.GetPerformanceRate(); } } 3/4/2014 33Guice - Evgeny Barabanov
  • 34. Unit testing with Guice and Mockito We’d like to test GetComputerPerformanceRate method. So lets do that! First, we create a module which defines @Provides methods for GraphicCard and HardDrive stubs: public class ComputerTestsModule extends AbstractModule { @Override protected void configure() { } @Provides IHardDrive provideHardDrive(){ IHardDrive hd = mock(IHardDrive.class); when(hd.CalculateSpeed()).thenReturn(5); return hd; } @Provides IGraphicCard provideGraphicCard(){ IGraphicCard gc = mock(IGraphicCard.class); when(gc.GetPerformanceRate()).thenReturn(10); return gc; } } 3/4/2014 34Guice - Evgeny Barabanov
  • 35. Unit testing with Guice and Mockito After we tell Guice to use our module instead of default binding for HardDrive and GraphicCard creation, we can unit test the desired class: public class ComputerTests extends TestCase { static Injector injector = Guice.createInjector(new ComputerTestsModule()); IComputer cpForTest = injector.getInstance(IComputer.class); @Test public void testComputerPerformance(){ assertEquals(15, cpForTest.GetComputerPerformanceRate()); } } 3/4/2014 35Guice - Evgeny Barabanov
  • 36. Best practices • Minimize mutability • Inject only direct dependencies • Avoid cyclic dependencies • Avoid static state • Use @Nullable • Create fast and side-effects free modules • Be careful about I/O in providers • Avoid conditional logic in modules • Keep constructors as hidden as possible 3/4/2014 36Guice - Evgeny Barabanov
  • 37. Useful links • FAQ • Using Guice with Google AppEngine 3/4/2014 37Guice - Evgeny Barabanov