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)]>
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