Java Mailing List Archive

http://www.gg3721.com/

Home » user.jmock »

Re: [jmock-user] mocking twitter api

Rick Fisk

2009-09-18

Replies: Find Java Web Hosting

Author LoginPost Reply
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@(protected)
>> 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@(protected)=[[],
>> [],
>> []],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


©2008 gg3721.com - Jax Systems, LLC, U.S.A.