I created a class that I call ServiceLocator that allows me to do 
lightweight dependency injection (as opposed to using a heavy library that 
requires annotation and/or reflection).

You can declare interfaces for things that you need mocked, register them 
with their proper implementations in your Application.onCreate, but then in 
your unit tests re-register those interfaces to the mock objects.  I've 
found that when I need to wait for Application.onCreate to finish in my 
unit tests, I derive them from ActivityTestCase and call 
getInstrumentation().waitForIdleSync();

Here's my class - you can copy it, or use the library it's in if you'd like.
https://github.com/aguynamedrich/beacon-utils/blob/master/Library/src/us/beacondigital/utils/ServiceLocator.java

in Application.onCreate, you'd do

ServiceLocator.register(FooInterface.class, FooImplementation.class);

And in your unit test setup, you'd do

ServiceLocator.register(FooInterface.class, MockFooImpl.class);

Then, in your code, you'd resolve your interfaces with

ServiceLocator.resolve(FooInterface.class);

Documented roughly here:
https://github.com/aguynamedrich/beacon-utils#to-use-servicelocator-as-a-dependency-container

On Sunday, March 23, 2014 9:37:13 PM UTC-7, Yuvi wrote:
>
>
>  Hi,
>     
> I am facing issue while unit testing :
>
> // Service class that have to be tested.
>
> class FooService extends Service{
>
>     public static FooService sFooService;
>
>     private Bar mBar = new Bar();
>     //Other private objects
>
>     @Override
>     protected void onCreate()
>     {
>         sFooService = this;
>     }
>
>     public static FooService getInstance()
>     {
>         return sFooService;
>     }
>
>     @Override
>     protected void onDestroy()
>     {
>         sFooService = null;
>     }
>
>     public void doSomething()
>     {
>         //do Some stuff here
>         if(done)
>         {
>             mBar.perfomAction(true);
>             // Now this performAction method doing many stuffs using some 
> other classes
>             // that may have dependency and initialized from some else. Hence 
> throwing exceptions.
>             // Therefore need to mock Bar class. but how ??
>         }
>         else
>         {
>             mBar.perfomAction(false);
>         }
>     }}
>
>
> // Test Class
>
> class FooTest extends ServiceTestCase<FooService>{
>
>     protected void setUp() throws Exception
>     {
>         super.setUp();
>         MockitoAnnotations.initMocks(this);
>         startService(new Intent(getContext(), FooService.class));
>
>     }
>
>     protected void tearDown() throws Exception
>     {
>         super.tearDown();
>     }
>
>     public void testdoSomething()
>     {
>         Bar bar = mock(bar.class);
>         doThrow(new RuntimeException re).when(bar).performAction(true);
>
>         //How to inject bar mocked object?
>
>         assertNotNull(FooService.getInstance());
>
>         try
>         {
>             FooService.getInstance().doSomeThing();
>             Assert.Fail("Runtime exception should be thrown");
>         }
>         catch (RuntimeException re)
>         {
>
>         }
>     }}
>
>
> Now, here how can I inject bar mocked object which is created using 
> Mockito ?
>
> I have googled this, and found that some guys suggested to create getter 
> and setter for Bar class. Which I don't think is a valid solution, because 
> there could be number of private object, that will be visible to outside 
> FooService class.
>
> Regards,
>
> Yuvi
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to