Showing posts with label testing. Show all posts
Showing posts with label testing. Show all posts

Tuesday, September 7, 2010

Integration Tests with Shiro and Nimble

Today we have a guest posting from Uris on the freenode.net #grails channel. I know he spent quite a bit of time trying to solve this issue so rather than keep it to himself he wanted to share it with everyone else.

I recently hit a road block when trying to do integration tests for some controllers that required an authenticated user. We were using Nimble plugin, which basically uses shiro for authentication. Nimble injects an instance of the authenticated user into each controller called 'authenticatedUser'. The particular controller we were testing required that an 'authenticatedUser' be passed on to a service to do a certain action. I kept getting the following error when running the test:


No SecurityManager accessible to the calling code, either bound to the
org.apache.shiro.util.ThreadContext or as a vm static singleton.
This is an invalid application configuration.
java.lang.IllegalStateException: No SecurityManager accessible to the
calling code, either bound to the org.apache.shiro.util.ThreadContext
or as a vm static singleton.
This is an invalid application configuration.
at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:115)
at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:57)
at org.apache.shiro.SecurityUtils$getSubject.call(Unknown Source)
at NimbleGrailsPlugin$_injectAuthn_closure8.doCall(NimbleGrailsPlugin.groovy:137)
at NimbleGrailsPlugin$_injectAuthn_closure8.doCall(NimbleGrailsPlugin.groovy)

I needed to find a way to mock an authenticated user into the test for the controller to use. After a lot of googling, volumes of java, and lots of Iron Maiden, we finally discovered how to do it. First we needed to mock an instance of org.apache.shiro.subject.Subject:

def subject = [getPrincipal: {863},
isAuthenticated: {true}
]as Subject

863 is the id of the default admin user created by Nimble during bootstrap. It might differ for another application, but in this particular case it is 863. Next we need to inject this Subject into org.apache.shiro.util.ThreadContext:

ThreadContext.put(ThreadContext.SECURITY_MANAGER_KEY,
[getSubject: {subject} as SecurityManager])

The final step is to make sure that Shiro's SecurityUtils returns an instance of Subject:

SecurityUtils.metaClass.static.getSubject = {subject}

The final code looks something like this:

import org.apache.shiro.util.ThreadContext
import org.apache.shiro.subject.Subject
import org.apache.shiro.SecurityUtils

def subject = [getPrincipal: {863},
isAuthenticated: {true}
]as Subject
ThreadContext.put(ThreadContext.SECURITY_MANAGER_KEY,
[getSubject: {subject} as SecurityManager])
SecurityUtils.metaClass.static.getSubject = {subject}

Saturday, September 4, 2010

Testing Grails UrlMappings

One thing that often gets overlooked in testing Grails applications is testing any changes you may have made to UrlMappings.groovy. It's understandable that this would happen, but here is how to fix that.

Let's say you have the following in your UrlMappings.groovy

class UrlMappings {
static mappings = {
"/login"(controller: "security", action:"login")
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
}

Really nothing much going on here with the one exception of the custom mapping of /login to the security controller login action. So that's really what we want to test, and here is how:

class UrlMappingsTestCase extends GrailsUrlMappingsTestCase {
void testMappings() {
assertUrlMapping("/login",
controller: "security",
action: "login"
)

assertForwardUrlMapping(500, view: "error")
}
}

That's the basics. Nothing too complicated going on here. I even threw in an example of testing status code (500 in this case) and forwarding. GrailsUrlMappingsTestCase has other asserts that can be used to test other types of mappings so you might want to to read the source.

Remember, as a rule of thumb: "If it's important enough to write, it's important enough to test."

Wednesday, September 1, 2010

Run last failed test, again!

In the course of fixing an issue or implementing a new feature you might just find yourself running your "grails test-app" over and over. Yes, you could also supply a pattern matcher to limit the things to test, but even better is the ability to just run the last failed tests using "grails test-app -rerun".

Monday, August 30, 2010

Code quality

Creating maintainable Grails applications isn't too tough. The convention over configuration approach of Grails helps address a lot of the problems suffered by larger applications in the maintenance phase. It's easy to find where bug fixes, changes, or enhancements should be applied.

However, this doesn't mean there is room for improvement. It's not a fundamental issue with Grails but applications in general. Having a proper set of test suites which cover the vast majority of the applications functionality goes a long way. That's why I have found the coverage plug-in so useful.

The coverage plug-in can help you identify areas within your application where your test coverage is lacking. This might even lead you to find out that the code is difficult to test and possibly designed incorrectly. I have found that if something is hard to test, then it's probably done wrong.

Along with the coverage plug-in, the codenarc plug-in can help you identify issues (some very minor) that will help you build more maintainable Grails applications.

So, take them for a spin and improve your Grails applications!

Saturday, August 28, 2010

Grails testing tips

Don't get me wrong, Grails is fantastic, but the documentation sometimes is lacking or completely wrong. I realize that development is moving so fast with Grails that documentation gets overlooked but this can be a source of frustration.

Often my frustration comes when I am trying to write effective tests and the documentation often send me (and my co-workers) down the wrong path.

In an effort to keep others from making the same mistakes I have made in the past, you may want to just check out the MockUtils implementation to see what Grails really has to offer during testing.

If you aren't familiar with testing in Grails then check out the sample chapter (which happens to be all about testing) from the book Grails in Action. If you don't already have a copy of the book, I recommend you get one. It's fantastic!

P.S. As a bonus here are some nice examples of testing REST controllers.