mocking twitter api

View: New views
5 Messages — Rating Filter:   Alert me  

mocking twitter api

by Rick Fisk-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I have a piece of code that attempts to post a status update to twitter.

    public static boolean tweetItem(String un, String pw, Item item, String link) {

        try {

            Twitter tw = new Twitter(un, pw);

            Twitter.Status status = tw.setStatus(com.quantum.util.StringUtil.buildSMSResponse(item, 140, link));

            log.debug(status.getId());

            //status.

        } catch (TwitterException e) {

            e.printStackTrace();

            return false;

        }

        return true;

    }


I want to mock the jtwitter API to test that the boolean is set
correctly (due to the way the API is coded, I have to use the Imposterizer)

I also don't want to run an integration test. ie; I don't want to
actually post something to twitter in the "success" scenario. This isn't
an integration test though I might make a separate integration test that
would actually post to twitter and then tear down the status update by
destroying it via the same twitter API.

I want to simulate both success and failure scenarios. This will also
allow me to later modify the way I am handling the exception so that a
more robust set of messages can be filtered back to the user. For
instance, if twitter is down, if the number of API calls has been
throttled etc, I want to notify the user more specifically. Any
improvements to the code would involve mocking various flavors of
IOExceptions delivered back through the API and thus messagized
appropriately back to the browser.

("Ooops - you've exceeded the threshold of API calls you can make, try
again later");

But I'm having a lot of trouble mocking either failure or success. Test
method looks like this for success:


public abstract class BaseManagerMockTestCase {

    //~ Static fields/initializers =============================================

    final protected Log log = LogFactory.getLog(getClass());

    protected ResourceBundle rb;

    protected Mockery context = new JUnit4Mockery() {{

      setImposteriser(ClassImposteriser.INSTANCE);  

    }};

 <snip>

}

public class ThisTest extends BaseManagerMockTestCase {

   <snip>

   @Before

   setUp {

    mockTwitter = context.mock(Twitter.class);

  }


  @Test
    public void testSuccessfulTweet() throws Exception {


        context.checking(new Expectations() {{
            one(mockTwitter).setStatus("foo");
            will(returnValue((Twitter.Status.class)));

        }});

        context.checking(new Expectations() {{
            oneOf(itemDao).getItem(Long.parseLong(itemId));
            will(returnValue(new Item()));
        }});

        Item item = itemManager.getItem("1");

        item.setDescription("foo foo foo");
        item.setLinkUrl("http://foo.com");
        item.setId(1L);
        item.setItemTemplateId(1L);

        assertNotNull(item.getDescription());
        assertNotNull(item);
        assertTrue(ItemExporter.tweetItem("testuser", "testpassword", item, "foo foo foo"));

    }


However, when I run this it results in a "never invoked" stack trace:

DEBUG [main] ItemExporter.tweetItem(14) | 4031156078 <----------------------- log output from code under test

java.lang.AssertionError: not all expectations were satisfied
expectations:
  expected once, never invoked: twitter.setStatus("foo"); returns <class com.quantum.service.integration.outbound.Twitter$Status>
  expected once, already invoked 1 time: itemDao.getItem(<1L>); returns <com.quantum.model.Item@c68c3[modifiedOn=Wed Sep 16 15:08:54 CDT 2009,description=foo foo foo,leadCount=0,published=false,linkUrl=http://rwrt.us/aag,images=[],itemTemplateId=1,externalUrl=<null>,createdOn=Wed Sep 16 15:08:54 CDT 2009,itemIdentifier=<null>,location=null null, null null,ownerId=<null>,accountId=<null>,sourceKey=<null>,firstImage=<null>,itemTemplate=com.quantum.model.ItemTemplate@406199[buckets=[[], [], []],id=<null>,attributeMaps=[],name=<null>,bucket2Label=<null>,includeLocationInText=false,bucket3Label=<null>],newImages=[],attributes=[],id=1]>
        at org.jmock.lib.AssertionErrorTranslator.translate(AssertionErrorTranslator.java:20)
        at org.jmock.Mockery.assertIsSatisfied(Mockery.java:196)


As you can see from the log output above, the API is successfully
posting to twitter and returning the Twitter.$Status object. This would
indicate to me, a noob with jmock, that my mocked class is completely
being ignored. I wanted to intercept the twitterAPI's "setStatus()
method and fake a return value. But it just isn't working.

Is it already obvious to the non-noobs what I'm doing wrong here? Is
this a case of failing to mock the object's instantiation? (new
Twitter("un","pw"))




---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: mocking twitter api

by Louis Rose-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Rick,

I'm a bit of JMock newbie myself, but I think I've run into this problem
too...

The instance of Twitter, tw, used in tweetItem(String, String, Item,
String) is not a mock object. It's an instance of the Twitter class. For
the test to pass, the implementation of tweetItem needs to use the
mockTwitter object constructed in the test.

A common solution to this kind of problem is to add a constructor to the
class-under-test with a parameter for each object that is to be mocked.
Assuming that tweetItem resides on the ItemExporter class, here is a
sample solution:

ItemExporter.java:

private final Twitter tw;

public ItemExporter(Twitter tw) {
        this.tw = tw;
}

public boolean tweetItem(String un, String pw, Item item, String link) {

        try {
                Twitter.Status status = tw.setStatus(...);
                ...

        } catch (TwitterException e) {
                ...
                return false;
        }

        return true;
}


And in the test, the last assertion would read:

assertTrue(new ItemExporter(mockTwitter).tweetItem("testuser",
"testpassword", item, "foo foo foo"))


One consequence of this solution is that the tweetItem method is no
longer static. This may or may not indicate that ItemExporter is no
longer the best class to own this method.

Hope this helps!

Cheers,
Louis.

----
Louis Rose
Research Student
Department of Computer Science,
University of York,
Heslington, York, YO10 5DD, United Kingdom.
+44 1904 434762
Twitter: @louismrose


Rick Fisk wrote:

> I have a piece of code that attempts to post a status update to twitter.
>
>    public static boolean tweetItem(String un, String pw, Item item,
> String link) {
>
>        try {
>
>            Twitter tw = new Twitter(un, pw);
>
>            Twitter.Status status =
> tw.setStatus(com.quantum.util.StringUtil.buildSMSResponse(item, 140,
> link));
>
>            log.debug(status.getId());
>
>            //status.
>
>        } catch (TwitterException e) {
>
>            e.printStackTrace();
>
>            return false;
>
>        }
>
>        return true;
>
>    }
>
>
> I want to mock the jtwitter API to test that the boolean is set
> correctly (due to the way the API is coded, I have to use the Imposterizer)
>
> I also don't want to run an integration test. ie; I don't want to
> actually post something to twitter in the "success" scenario. This isn't
> an integration test though I might make a separate integration test that
> would actually post to twitter and then tear down the status update by
> destroying it via the same twitter API.
>
> I want to simulate both success and failure scenarios. This will also
> allow me to later modify the way I am handling the exception so that a
> more robust set of messages can be filtered back to the user. For
> instance, if twitter is down, if the number of API calls has been
> throttled etc, I want to notify the user more specifically. Any
> improvements to the code would involve mocking various flavors of
> IOExceptions delivered back through the API and thus messagized
> appropriately back to the browser.
>
> ("Ooops - you've exceeded the threshold of API calls you can make, try
> again later");
>
> But I'm having a lot of trouble mocking either failure or success. Test
> method looks like this for success:
>
>
> public abstract class BaseManagerMockTestCase {
>
>    //~ Static fields/initializers
> =============================================
>
>    final protected Log log = LogFactory.getLog(getClass());
>
>    protected ResourceBundle rb;
>
>    protected Mockery context = new JUnit4Mockery() {{
>
>      setImposteriser(ClassImposteriser.INSTANCE);
>    }};
>
> <snip>
>
> }
>
> public class ThisTest extends BaseManagerMockTestCase {
>
>   <snip>
>
>   @Before
>
>   setUp {
>
>    mockTwitter = context.mock(Twitter.class);
>
>  }
>
>
>  @Test
>    public void testSuccessfulTweet() throws Exception {
>
>
>        context.checking(new Expectations() {{
>            one(mockTwitter).setStatus("foo");
>            will(returnValue((Twitter.Status.class)));
>
>        }});
>
>        context.checking(new Expectations() {{
>            oneOf(itemDao).getItem(Long.parseLong(itemId));
>            will(returnValue(new Item()));
>        }});
>
>        Item item = itemManager.getItem("1");
>
>        item.setDescription("foo foo foo");
>        item.setLinkUrl("http://foo.com");
>        item.setId(1L);
>        item.setItemTemplateId(1L);
>
>        assertNotNull(item.getDescription());
>        assertNotNull(item);
>        assertTrue(ItemExporter.tweetItem("testuser", "testpassword",
> item, "foo foo foo"));
>
>    }
>
>
> However, when I run this it results in a "never invoked" stack trace:
>
> DEBUG [main] ItemExporter.tweetItem(14) | 4031156078
> <----------------------- log output from code under test
>
> java.lang.AssertionError: not all expectations were satisfied
> expectations:
>  expected once, never invoked: twitter.setStatus("foo"); returns <class
> com.quantum.service.integration.outbound.Twitter$Status>
>  expected once, already invoked 1 time: itemDao.getItem(<1L>); returns
> <com.quantum.model.Item@c68c3[modifiedOn=Wed Sep 16 15:08:54 CDT
> 2009,description=foo foo
> foo,leadCount=0,published=false,linkUrl=http://rwrt.us/aag,images=[],itemTemplateId=1,externalUrl=<null>,createdOn=Wed
> Sep 16 15:08:54 CDT 2009,itemIdentifier=<null>,location=null null, null
> null,ownerId=<null>,accountId=<null>,sourceKey=<null>,firstImage=<null>,itemTemplate=com.quantum.model.ItemTemplate@406199[buckets=[[],
> [],
> []],id=<null>,attributeMaps=[],name=<null>,bucket2Label=<null>,includeLocationInText=false,bucket3Label=<null>],newImages=[],attributes=[],id=1]>
>
>     at
> org.jmock.lib.AssertionErrorTranslator.translate(AssertionErrorTranslator.java:20)
>
>     at org.jmock.Mockery.assertIsSatisfied(Mockery.java:196)
>
>
> As you can see from the log output above, the API is successfully
> posting to twitter and returning the Twitter.$Status object. This would
> indicate to me, a noob with jmock, that my mocked class is completely
> being ignored. I wanted to intercept the twitterAPI's "setStatus()
> method and fake a return value. But it just isn't working.
>
> Is it already obvious to the non-noobs what I'm doing wrong here? Is
> this a case of failing to mock the object's instantiation? (new
> Twitter("un","pw"))
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: mocking twitter api

by Steve Freeman-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

it looks like you're not calling the mock Twitter instance you've set  
up. You create a mock Twitter in the test, but then use a different  
instance in the body of the code. You need to find a way to pass the  
mock instance into the code, which is the point at which interesting  
design moments happen.

One more point, you can set up multiple expectations within a single  
checking clause. You don't need to write one per mock.

S

On 16 Sep 2009, at 21:24, Rick Fisk wrote:

> I have a piece of code that attempts to post a status update to  
> twitter.
>
>   public static boolean tweetItem(String un, String pw, Item item,  
> String link) {
>
>       try {
>
>           Twitter tw = new Twitter(un, pw);
>
>           Twitter.Status status =  
> tw.setStatus(com.quantum.util.StringUtil.buildSMSResponse(item, 140,  
> link));
>
>           log.debug(status.getId());
>
>           //status.
>
>       } catch (TwitterException e) {
>
>           e.printStackTrace();
>
>           return false;
>
>       }
>
>       return true;
>
>   }
>
>
> I want to mock the jtwitter API to test that the boolean is set  
> correctly (due to the way the API is coded, I have to use the  
> Imposterizer)
>
> I also don't want to run an integration test. ie; I don't want to  
> actually post something to twitter in the "success" scenario. This  
> isn't an integration test though I might make a separate integration  
> test that would actually post to twitter and then tear down the  
> status update by destroying it via the same twitter API.
>
> I want to simulate both success and failure scenarios. This will  
> also allow me to later modify the way I am handling the exception so  
> that a more robust set of messages can be filtered back to the user.  
> For instance, if twitter is down, if the number of API calls has  
> been throttled etc, I want to notify the user more specifically. Any  
> improvements to the code would involve mocking various flavors of  
> IOExceptions delivered back through the API and thus messagized  
> appropriately back to the browser.
>
> ("Ooops - you've exceeded the threshold of API calls you can make,  
> try again later");
>
> But I'm having a lot of trouble mocking either failure or success.  
> Test method looks like this for success:
>
>
> public abstract class BaseManagerMockTestCase {
>
>   //~ Static fields/initializers  
> =============================================
>
>   final protected Log log = LogFactory.getLog(getClass());
>
>   protected ResourceBundle rb;
>
>   protected Mockery context = new JUnit4Mockery() {{
>
>     setImposteriser(ClassImposteriser.INSTANCE);
>   }};
>
> <snip>
>
> }
>
> public class ThisTest extends BaseManagerMockTestCase {
>
>  <snip>
>
>  @Before
>
>  setUp {
>
>   mockTwitter = context.mock(Twitter.class);
>
> }
>
>
> @Test
>   public void testSuccessfulTweet() throws Exception {
>
>
>       context.checking(new Expectations() {{
>           one(mockTwitter).setStatus("foo");
>           will(returnValue((Twitter.Status.class)));
>
>       }});
>
>       context.checking(new Expectations() {{
>           oneOf(itemDao).getItem(Long.parseLong(itemId));
>           will(returnValue(new Item()));
>       }});
>
>       Item item = itemManager.getItem("1");
>
>       item.setDescription("foo foo foo");
>       item.setLinkUrl("http://foo.com");
>       item.setId(1L);
>       item.setItemTemplateId(1L);
>
>       assertNotNull(item.getDescription());
>       assertNotNull(item);
>       assertTrue(ItemExporter.tweetItem("testuser", "testpassword",  
> item, "foo foo foo"));
>
>   }
>
>
> However, when I run this it results in a "never invoked" stack trace:
>
> DEBUG [main] ItemExporter.tweetItem(14) | 4031156078  
> <----------------------- log output from code under test
>
> java.lang.AssertionError: not all expectations were satisfied
> expectations:
> expected once, never invoked: twitter.setStatus("foo"); returns  
> <class com.quantum.service.integration.outbound.Twitter$Status>
> expected once, already invoked 1 time: itemDao.getItem(<1L>);  
> returns <com.quantum.model.Item@c68c3[modifiedOn=Wed Sep 16 15:08:54  
> CDT 2009,description=foo foo foo,leadCount=0,published=false,linkUrl=http://rwrt.us/aag,images= 
> [],itemTemplateId=1,externalUrl=<null>,createdOn=Wed Sep 16 15:08:54  
> CDT 2009,itemIdentifier=<null>,location=null null, null  
> null
> ,ownerId
> =
> <
> null
> >
> ,accountId
> =
> <
> null
> >
> ,sourceKey
> =
> <
> null
> >
> ,firstImage
> =
> <
> null
> >,itemTemplate=com.quantum.model.ItemTemplate@406199[buckets=[[],  
> [],  
> []],id
> =
> <
> null
> >
> ,attributeMaps
> =
> [],name
> =
> <
> null
> >
> ,bucket2Label
> =
> <
> null
> >
> ,includeLocationInText
> =false,bucket3Label=<null>],newImages=[],attributes=[],id=1]>
> at  
> org
> .jmock
> .lib
> .AssertionErrorTranslator.translate(AssertionErrorTranslator.java:20)
> at org.jmock.Mockery.assertIsSatisfied(Mockery.java:196)
>
>
> As you can see from the log output above, the API is successfully  
> posting to twitter and returning the Twitter.$Status object. This  
> would indicate to me, a noob with jmock, that my mocked class is  
> completely being ignored. I wanted to intercept the twitterAPI's  
> "setStatus() method and fake a return value. But it just isn't  
> working.
>
> Is it already obvious to the non-noobs what I'm doing wrong here? Is  
> this a case of failing to mock the object's instantiation? (new  
> Twitter("un","pw"))
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>   http://xircles.codehaus.org/manage_email
>
>

Steve Freeman
Winner of the Agile Alliance Gordon Pask award 2006

http://www.m3p.co.uk

M3P Limited.
Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ.
Company registered in England & Wales. Number 03689627



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: mocking twitter api

by Rick Fisk-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks for the tips. I added a setter to the code and conditionally
execute it at run-time. It only gets set from the test, otherwise the
code instantiates a new jtwitter object and runs normally. Thanks for
the help. Works like a charm.



Steve Freeman wrote:

> it looks like you're not calling the mock Twitter instance you've set
> up. You create a mock Twitter in the test, but then use a different
> instance in the body of the code. You need to find a way to pass the
> mock instance into the code, which is the point at which interesting
> design moments happen.
>
> One more point, you can set up multiple expectations within a single
> checking clause. You don't need to write one per mock.
>
> S
>
> On 16 Sep 2009, at 21:24, Rick Fisk wrote:
>> I have a piece of code that attempts to post a status update to twitter.
>>
>>   public static boolean tweetItem(String un, String pw, Item item,
>> String link) {
>>
>>       try {
>>
>>           Twitter tw = new Twitter(un, pw);
>>
>>           Twitter.Status status =
>> tw.setStatus(com.quantum.util.StringUtil.buildSMSResponse(item, 140,
>> link));
>>
>>           log.debug(status.getId());
>>
>>           //status.
>>
>>       } catch (TwitterException e) {
>>
>>           e.printStackTrace();
>>
>>           return false;
>>
>>       }
>>
>>       return true;
>>
>>   }
>>
>>
>> I want to mock the jtwitter API to test that the boolean is set
>> correctly (due to the way the API is coded, I have to use the
>> Imposterizer)
>>
>> I also don't want to run an integration test. ie; I don't want to
>> actually post something to twitter in the "success" scenario. This
>> isn't an integration test though I might make a separate integration
>> test that would actually post to twitter and then tear down the
>> status update by destroying it via the same twitter API.
>>
>> I want to simulate both success and failure scenarios. This will also
>> allow me to later modify the way I am handling the exception so that
>> a more robust set of messages can be filtered back to the user. For
>> instance, if twitter is down, if the number of API calls has been
>> throttled etc, I want to notify the user more specifically. Any
>> improvements to the code would involve mocking various flavors of
>> IOExceptions delivered back through the API and thus messagized
>> appropriately back to the browser.
>>
>> ("Ooops - you've exceeded the threshold of API calls you can make,
>> try again later");
>>
>> But I'm having a lot of trouble mocking either failure or success.
>> Test method looks like this for success:
>>
>>
>> public abstract class BaseManagerMockTestCase {
>>
>>   //~ Static fields/initializers
>> =============================================
>>
>>   final protected Log log = LogFactory.getLog(getClass());
>>
>>   protected ResourceBundle rb;
>>
>>   protected Mockery context = new JUnit4Mockery() {{
>>
>>     setImposteriser(ClassImposteriser.INSTANCE);
>>   }};
>>
>> <snip>
>>
>> }
>>
>> public class ThisTest extends BaseManagerMockTestCase {
>>
>>  <snip>
>>
>>  @Before
>>
>>  setUp {
>>
>>   mockTwitter = context.mock(Twitter.class);
>>
>> }
>>
>>
>> @Test
>>   public void testSuccessfulTweet() throws Exception {
>>
>>
>>       context.checking(new Expectations() {{
>>           one(mockTwitter).setStatus("foo");
>>           will(returnValue((Twitter.Status.class)));
>>
>>       }});
>>
>>       context.checking(new Expectations() {{
>>           oneOf(itemDao).getItem(Long.parseLong(itemId));
>>           will(returnValue(new Item()));
>>       }});
>>
>>       Item item = itemManager.getItem("1");
>>
>>       item.setDescription("foo foo foo");
>>       item.setLinkUrl("http://foo.com");
>>       item.setId(1L);
>>       item.setItemTemplateId(1L);
>>
>>       assertNotNull(item.getDescription());
>>       assertNotNull(item);
>>       assertTrue(ItemExporter.tweetItem("testuser", "testpassword",
>> item, "foo foo foo"));
>>
>>   }
>>
>>
>> However, when I run this it results in a "never invoked" stack trace:
>>
>> DEBUG [main] ItemExporter.tweetItem(14) | 4031156078
>> <----------------------- log output from code under test
>>
>> java.lang.AssertionError: not all expectations were satisfied
>> expectations:
>> expected once, never invoked: twitter.setStatus("foo"); returns
>> <class com.quantum.service.integration.outbound.Twitter$Status>
>> expected once, already invoked 1 time: itemDao.getItem(<1L>); returns
>> <com.quantum.model.Item@c68c3[modifiedOn=Wed Sep 16 15:08:54 CDT
>> 2009,description=foo foo
>> foo,leadCount=0,published=false,linkUrl=http://rwrt.us/aag,images=[],itemTemplateId=1,externalUrl=<null>,createdOn=Wed
>> Sep 16 15:08:54 CDT 2009,itemIdentifier=<null>,location=null null,
>> null
>> null,ownerId=<null>,accountId=<null>,sourceKey=<null>,firstImage=<null>,itemTemplate=com.quantum.model.ItemTemplate@406199[buckets=[[],
>> [],
>> []],id=<null>,attributeMaps=[],name=<null>,bucket2Label=<null>,includeLocationInText=false,bucket3Label=<null>],newImages=[],attributes=[],id=1]>
>>
>>     at
>> org.jmock.lib.AssertionErrorTranslator.translate(AssertionErrorTranslator.java:20)
>>
>>     at org.jmock.Mockery.assertIsSatisfied(Mockery.java:196)
>>
>>
>> As you can see from the log output above, the API is successfully
>> posting to twitter and returning the Twitter.$Status object. This
>> would indicate to me, a noob with jmock, that my mocked class is
>> completely being ignored. I wanted to intercept the twitterAPI's
>> "setStatus() method and fake a return value. But it just isn't working.
>>
>> Is it already obvious to the non-noobs what I'm doing wrong here? Is
>> this a case of failing to mock the object's instantiation? (new
>> Twitter("un","pw"))
>>
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>
>>   http://xircles.codehaus.org/manage_email
>>
>>
>
> Steve Freeman
> Winner of the Agile Alliance Gordon Pask award 2006
>
> http://www.m3p.co.uk
>
> M3P Limited.
> Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ.
> Company registered in England & Wales. Number 03689627
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: mocking twitter api

by Stephen Smith-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi

Glad the solution worked, but have you considered using Dependency Injection to
inject the Twitter object rather than having a setter?

S

Rick Fisk wrote:

> Thanks for the tips. I added a setter to the code and conditionally
> execute it at run-time. It only gets set from the test, otherwise the
> code instantiates a new jtwitter object and runs normally. Thanks for
> the help. Works like a charm.
>
>
>
> Steve Freeman wrote:
>> it looks like you're not calling the mock Twitter instance you've set
>> up. You create a mock Twitter in the test, but then use a different
>> instance in the body of the code. You need to find a way to pass the
>> mock instance into the code, which is the point at which interesting
>> design moments happen.
>>
>> One more point, you can set up multiple expectations within a single
>> checking clause. You don't need to write one per mock.
>>
>> S
>>
>> On 16 Sep 2009, at 21:24, Rick Fisk wrote:
>>> I have a piece of code that attempts to post a status update to twitter.
>>>
>>>   public static boolean tweetItem(String un, String pw, Item item,
>>> String link) {
>>>
>>>       try {
>>>
>>>           Twitter tw = new Twitter(un, pw);
>>>
>>>           Twitter.Status status =
>>> tw.setStatus(com.quantum.util.StringUtil.buildSMSResponse(item, 140,
>>> link));
>>>
>>>           log.debug(status.getId());
>>>
>>>           //status.
>>>
>>>       } catch (TwitterException e) {
>>>
>>>           e.printStackTrace();
>>>
>>>           return false;
>>>
>>>       }
>>>
>>>       return true;
>>>
>>>   }
>>>
>>>
>>> I want to mock the jtwitter API to test that the boolean is set
>>> correctly (due to the way the API is coded, I have to use the
>>> Imposterizer)
>>>
>>> I also don't want to run an integration test. ie; I don't want to
>>> actually post something to twitter in the "success" scenario. This
>>> isn't an integration test though I might make a separate integration
>>> test that would actually post to twitter and then tear down the
>>> status update by destroying it via the same twitter API.
>>>
>>> I want to simulate both success and failure scenarios. This will also
>>> allow me to later modify the way I am handling the exception so that
>>> a more robust set of messages can be filtered back to the user. For
>>> instance, if twitter is down, if the number of API calls has been
>>> throttled etc, I want to notify the user more specifically. Any
>>> improvements to the code would involve mocking various flavors of
>>> IOExceptions delivered back through the API and thus messagized
>>> appropriately back to the browser.
>>>
>>> ("Ooops - you've exceeded the threshold of API calls you can make,
>>> try again later");
>>>
>>> But I'm having a lot of trouble mocking either failure or success.
>>> Test method looks like this for success:
>>>
>>>
>>> public abstract class BaseManagerMockTestCase {
>>>
>>>   //~ Static fields/initializers
>>> =============================================
>>>
>>>   final protected Log log = LogFactory.getLog(getClass());
>>>
>>>   protected ResourceBundle rb;
>>>
>>>   protected Mockery context = new JUnit4Mockery() {{
>>>
>>>     setImposteriser(ClassImposteriser.INSTANCE);
>>>   }};
>>>
>>> <snip>
>>>
>>> }
>>>
>>> public class ThisTest extends BaseManagerMockTestCase {
>>>
>>>  <snip>
>>>
>>>  @Before
>>>
>>>  setUp {
>>>
>>>   mockTwitter = context.mock(Twitter.class);
>>>
>>> }
>>>
>>>
>>> @Test
>>>   public void testSuccessfulTweet() throws Exception {
>>>
>>>
>>>       context.checking(new Expectations() {{
>>>           one(mockTwitter).setStatus("foo");
>>>           will(returnValue((Twitter.Status.class)));
>>>
>>>       }});
>>>
>>>       context.checking(new Expectations() {{
>>>           oneOf(itemDao).getItem(Long.parseLong(itemId));
>>>           will(returnValue(new Item()));
>>>       }});
>>>
>>>       Item item = itemManager.getItem("1");
>>>
>>>       item.setDescription("foo foo foo");
>>>       item.setLinkUrl("http://foo.com");
>>>       item.setId(1L);
>>>       item.setItemTemplateId(1L);
>>>
>>>       assertNotNull(item.getDescription());
>>>       assertNotNull(item);
>>>       assertTrue(ItemExporter.tweetItem("testuser", "testpassword",
>>> item, "foo foo foo"));
>>>
>>>   }
>>>
>>>
>>> However, when I run this it results in a "never invoked" stack trace:
>>>
>>> DEBUG [main] ItemExporter.tweetItem(14) | 4031156078
>>> <----------------------- log output from code under test
>>>
>>> java.lang.AssertionError: not all expectations were satisfied
>>> expectations:
>>> expected once, never invoked: twitter.setStatus("foo"); returns
>>> <class com.quantum.service.integration.outbound.Twitter$Status>
>>> expected once, already invoked 1 time: itemDao.getItem(<1L>); returns
>>> <com.quantum.model.Item@c68c3[modifiedOn=Wed Sep 16 15:08:54 CDT
>>> 2009,description=foo foo
>>> foo,leadCount=0,published=false,linkUrl=http://rwrt.us/aag,images=[],itemTemplateId=1,externalUrl=<null>,createdOn=Wed
>>> Sep 16 15:08:54 CDT 2009,itemIdentifier=<null>,location=null null,
>>> null
>>> null,ownerId=<null>,accountId=<null>,sourceKey=<null>,firstImage=<null>,itemTemplate=com.quantum.model.ItemTemplate@406199[buckets=[[],
>>> [],
>>> []],id=<null>,attributeMaps=[],name=<null>,bucket2Label=<null>,includeLocationInText=false,bucket3Label=<null>],newImages=[],attributes=[],id=1]>
>>>
>>>     at
>>> org.jmock.lib.AssertionErrorTranslator.translate(AssertionErrorTranslator.java:20)
>>>
>>>     at org.jmock.Mockery.assertIsSatisfied(Mockery.java:196)
>>>
>>>
>>> As you can see from the log output above, the API is successfully
>>> posting to twitter and returning the Twitter.$Status object. This
>>> would indicate to me, a noob with jmock, that my mocked class is
>>> completely being ignored. I wanted to intercept the twitterAPI's
>>> "setStatus() method and fake a return value. But it just isn't working.
>>>
>>> Is it already obvious to the non-noobs what I'm doing wrong here? Is
>>> this a case of failing to mock the object's instantiation? (new
>>> Twitter("un","pw"))
>>>
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe from this list, please visit:
>>>
>>>   http://xircles.codehaus.org/manage_email
>>>
>>>
>>
>> Steve Freeman
>> Winner of the Agile Alliance Gordon Pask award 2006
>>
>> http://www.m3p.co.uk
>>
>> M3P Limited.
>> Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ.
>> Company registered in England & Wales. Number 03689627
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>
>>    http://xircles.codehaus.org/manage_email
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>
>

--
Stephen Smith
http://www.stephen-smith.co.uk/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email