Problems with mocking object for several layers of application

22 views
Skip to first unread message

sheffanet

unread,
Jun 7, 2011, 3:49:32 AM6/7/11
to Android Mock Discussion
Hello,
I am using RoboGuice and Android Mock frameworks.
I have problem with mocking object.

I have:

public class MyManager implements IMyManager {

@Inject
private IMyDao dao;

@Override
public Account doSmth(String value) {
return dao.getSomth(value); //
always new dao
}
}

I have test:

public class MyClassManagerTest extends
RoboUnitTestCase<MyApplication> {

private IMyDao dao;
private IMyManager manager;

@Override
protected void setUp() throws Exception {
super.setUp();
Injector injector = Guice.createInjector();
manager = injector.getInstance(MyManager.class);
dao = injector.getInstance(MyDao.class);
}

@MediumTest
@UsesMocks(MyDao.class)
public void testMock() {
Account account = new Account();
account.setName("TestAccount");

dao = AndroidMock.createMock(MyDao.class);
Android.expect(dao.getSomth("test")).andReturn(account);
AndroidMock.replay(dao);

Account accountFromDB = manager.doSmth("test"); // Problems
start here

assertEquals(account.getName(), accountFromDB.getName());
}
}

The problem is when I run manager method.
In my case I have mocked DAO, but when I run MyManager's method, DAO
is not mocked inside MyManager class. In MyManager I alwasy have new
DAO object.
How to fix this problem?
Any suggestion?

Thanks,
Oleg

Stephen Woodward

unread,
Jun 7, 2011, 4:09:33 PM6/7/11
to androi...@googlegroups.com

Hi Oleg,

I've never used Guice or RoboGuice, so I might be taking a wrong turn here, but take a look at http://code.google.com/p/roboguice/source/browse/astroboy/src/roboguice/astroboy/AstroboyModule.java

In particular, have a look at line 40: bind(TalkingThing.class).to(TalkingThingMockImpl.class);

AstroboyModule (eventually) extends com.google.inject.AbstractModule

Instead of TalkingThing and TalkingThingMockImpl, you could provide MyDao and MyMockDao, where an instance of MyMockDao would just pass all calls into dao (AndroidMock.createMock( MyDao.class )).  You could even try MyDaoDelegateSubclass.class instead of MyMockDao although you're starting to get into the bowels of AndroidMock at that point and may well find more trouble than it's worth.

Even simpler may be to add a setDao on MyManager to allow you to set MyManager.dao.  Your test would then become:

       @UsesMocks(MyDao.class)
       public void testMock() {
               Account account = new Account();
               account.setName("TestAccount");

               dao = AndroidMock.createMock(MyDao.class);
               Android.expect(dao.getSomth("test")).andReturn(account);
               AndroidMock.replay(dao);

               manager.setDao(dao);


               Account accountFromDB = manager.doSmth("test");

               assertEquals(account.getName(), accountFromDB.getName());
       }

Hope that helps,

Steve

sheffanet

unread,
Jun 9, 2011, 2:55:16 AM6/9/11
to Android Mock Discussion
Hello.
Thanks for your attention.
Binding is important part of using RoboGuice in application. Without
using it I will not have possibility to instantiate my objects in main
and test applications.
There is only one solution which works in my case. Need to set DAO
object directly, as you wrote:
manager.setDao(dao);

Thank you,
Oleg

On Jun 7, 11:09 pm, Stephen Woodward <sd.woodwar...@gmail.com> wrote:
> Hi Oleg,
>
> I've never used Guice or RoboGuice, so I might be taking a wrong turn here,
> but take a look athttp://code.google.com/p/roboguice/source/browse/astroboy/src/robogui...
>
> In particular, have a look at line 40: bind(TalkingThing.class).to(
> TalkingThingMockImpl.class);
>
> AstroboyModule (eventually) extends *com.google.inject.AbstractModule*
>
> Instead of TalkingThing and TalkingThingMockImpl, you could provide MyDao
> and MyMockDao, where an instance of MyMockDao would just pass all calls into
> dao (AndroidMock.createMock( MyDao.class )).  You could even try
> MyDaoDelegateSubclass.class instead of MyMockDao although you're starting to
> get into the bowels of AndroidMock at that point and may well find more
> trouble than it's worth.
>
> Even simpler may be to add a setDao on MyManager to allow you to set
> MyManager.dao.  Your test would then become:
>
>        @UsesMocks(MyDao.class)
>        public void testMock() {
>                Account account = new Account();
>                account.setName("TestAccount");
>
>                dao = AndroidMock.createMock(MyDao.class);
>                Android.expect(dao.getSomth("test")).andReturn(account);
>                AndroidMock.replay(dao);
>                manager.setDao(dao);
>
>                Account accountFromDB = manager.doSmth("test");
>
>                assertEquals(account.getName(), accountFromDB.getName());
>        }
>
> Hope that helps,
>
> Steve
Reply all
Reply to author
Forward
0 new messages