views:

303

answers:

1

I like Spring MVC because you can unit test your controllers.

But testing controllers that oauth is another thing. For instance if I want to get the authorization url because I want to Oauth to GData, I would have to deploy the web-app because Google will only accept authorization requests from my domain (the url of my web app), not my development environment whose domain is localhost:8080.

So right now the only way I am testing if my code works is deploying the code and printing out the data that I need to have printed.

My Controller, which is a multi-action controller

public ModelAndView authorize(HttpServletRequest request,
HttpServletResponse response) {

        Provider provider = getProvider(request.getAttribute("provider"));
        String authUrl = provider.getAuthUrl();  
        page.put("authUrl", authUrl);
        return new ModelAndView("setup","model",page);
}

The provider code, all my dependencies are injected

public String getAuthUrl()
{
    oAuthParameters.setScope("http://docs.google.com/feeds/");   
    try {
       oAuthHelper.getUnauthorizedRequestToken(oAuthParameters);
    } catch (OAuthException e) {
        page.put("authUrl", CANNOT_CONNECT_TO_GOOGLE);
    }
    String oAuth_Callback="[callback url]";
    try {
        oAuth_Callback.concat("?oauth_token_secret=").concat(
            java.net.URLEncoder.encode
           (oAuthParameters.getOAuthTokenSecret(), "UTF-8"));
    } catch (UnsupportedEncodingException e) {
     page.put("authUrl",INTERNAL_ERROR);
    }

    oAuthParameters.setOAuthCallback(oAuth_Callback);
    String authUrl = oAuthHelper.createUserAuthorizationUrl(oAuthParameters);
    return authUrl;
}
+2  A: 

It sounds like you have one component (a controller) doing multiple things.

I would break this into

  1. The controller
  2. The OAuth service that communicates with Google

The latter should be injected into your controller, as with just about everything else in Spring.

This allows you, in a unit test, to mock out how your controller behaves when the OAuth component returns different values.

For actually testing integration with Google, you could do two things:

  1. Unit testing of the service that parses the Google OAuth response - mock out the code that does the actual message transport so that you can test how your message parser behaves when google returns a certain type of XML (I'm assuming this is done with XML, but same principle applies regardless of technology) vs another type.
  2. Actual integration tests of the component that sends and receives to google - this might be harder because of the limitations you mentioned.

So, even if they restrict access to certain domains, then you can unit test most of the pieces of the puzzle, and hopefully only have one small segment that has to be "in the wild" to be tested.

Or, could you register a different account for a domain in your test environment? Either way, you should still break up this code into smaller components.

matt b
My controller is actually very simple, it just gets the authorization Url in Google (see my updated post). Unit-testing the controller, I get get the authUrl from the model and do an assertNotNull(authUrl) which of course fails because it doesn't come from my domain. But here's the thing, when I run as web app and test it manually on localhost:8080, the jsp prints a url! And when I put the url in the browser it directs me to a page asking me to authorize the web app I made. X(
Jeune