Do you want to ROC or be Groovy?
March 26th, 2013
Compares Resource Oriented Computing to Groovy as development platforms for enterprise computing.
On a recent client project, I used the Facebook SDK plugin (http://grails.org/plugin/facebook-sdk) to integrate Facebook into our Grails app. I’ve never worked with this plugin before (or done any Facebook development for that matter), so it was a learning experience. It’s a nice plugin, and makes working with Facebook much, much easier.
There isn’t any information out there about testing this, so I thought I would share a few simple examples for people who are just starting out. These examples can be tested by simply modifying the code that comes with the sample code (https://github.com/benorama/grails-facebook-sdk-demo), then adding a test class for the WebsiteController.
The example below is a very trivial example, and meant to only demonstrate how to mock some of these objects. I made some modifications to the sample code that comes with the plugin to make it shorter for this example. Here’s what my sample controller code looks like now…
import com.restfb.exception.FacebookOAuthException
import grails.plugin.facebooksdk.FacebookContext
import grails.plugin.facebooksdk.FacebookGraphClient
import grails.converters.JSON
class WebsiteController {
static defaultAction = 'index'
FacebookContext facebookContext
def beforeInterceptor = {
log.info "START ${actionUri} with params=${params}"
}
def afterInterceptor = {
log.info "END ${actionUri}"
}
def index = {
if (facebookContext.app.id && facebookContext.authenticated) {
String token = facebookContext.user.token
if (token) {
try {
def user = getDataFromFacebook(token, facebookContext.user.id.toString())
//do something with user
} catch (FacebookOAuthException exception) {
//handle exception
}
}
}
}
def publishPost = {
try {
def user = getDataFromFacebook(facebookContext.user.token, facebookContext.user.id.toString())
//do something with user
} catch (Exception e) {
Map resp = [status: 'error', message: g.message(code: "generic.system.error")]
render resp as JSON
}
Map resp = [status: 'success', message: 'Message published']
render resp as JSON
}
def getDataFromFacebook(token, userId) {
FacebookGraphClient facebookGraphClient = new FacebookGraphClient(token)
return facebookGraphClient.fetchObject(userId)
}
}
There are two actions in this controller; the default index action (which I modified from the downloaded sample code), and a publishPost action which returns a JSON response.
Here is my test class with two simple tests, one for each action…
import grails.test.mixin.*
import grails.plugin.facebooksdk.FacebookContext
import grails.plugin.facebooksdk.FacebookContextUser
@TestFor(WebsiteController)
class WebsiteControllerTests {
void setUp() {}
void tearDown() {}
void testIndex() {
def facebookContext = mockFor(FacebookContext)
def facebookContextUser = mockFor(FacebookContextUser)
def facebookContextApp = mockFor(FacebookContextApp)
def facebookUser
def facebookUserId = "56789"
facebookContext.demand.isAuthenticated { -> return true }
facebookContextApp.demand.getId { -> return 24 }
facebookContextUser.demand.getToken { -> return "123456789" }
facebookContextUser.demand.getId { -> return facebookUserId }
controller.metaClass.getDataFromFacebook{ token, userId ->
facebookUser = ["firstName":"TestFirst", "lastName":"TestLast", "userId":userId]
return facebookUser
}
controller.facebookContext = facebookContext.createMock()
controller.facebookContext.user = facebookContextUser.createMock()
controller.facebookContext.app = facebookContextApp.createMock()
controller.index()
assert facebookUserId == facebookUser.userId
}
void testPublishPost() {
def facebookContext = mockFor(FacebookContext)
def facebookContextUser = mockFor(FacebookContextUser)
def facebookUser
def facebookUserId = "56789"
facebookContextUser.demand.getToken { -> return "123456789" }
facebookContextUser.demand.getId { -> return facebookUserId }
controller.metaClass.getDataFromFacebook{ token, userId ->
facebookUser = ["firstName":"TestFirst", "lastName":"TestLast", "userId":userId]
return facebookUser
}
controller.facebookContext = facebookContext.createMock()
controller.facebookContext.user = facebookContextUser.createMock()
controller.publishPost()
assert '{"status":"success","message":"Message published"}' == response.text
assert "success" == response.json.status
}
}
You should be able to copy and paste this code, and the tests should pass. Then you can play around with the code and start writing more tests that fit with your code.
Hopefully these examples will help someone else with testing code that uses the Facebook SDK Grails plugin.
Compares Resource Oriented Computing to Groovy as development platforms for enterprise computing.
This details a way to create tests similar to FItnesse query fixtures using the Spock framework.
How to deal with dependency resolution changes for plugins in Grails 2.2 without the workaround, by publishing your plugins as Maven artifacts.
Insert bio here