Ken Rimple heads Chariot Solutions' training and mentoring programs, and has developed and/or delivered courseware and seminars in a variety of technologies such as Maven, OSGi, Groovy, Grails and Spring. Throughout his career, Ken has always made it a priority to teach others what he has learned. Ken has served as the technical co-chair of both the Fall Forecast 2008 Cloud Computing Conference and the 2009 - 2012 Emerging Technologies for the Enterprise conferences. He hosts a popular podcast, the Chariot TechCast, and has led or participated in projects written in Java since Java 1.0.2. Ken taught the first Philadelphia-area Sun Introduction to Java course in the late 1990s. He is the co-author (along with Srini Penchikala) of Spring Roo in Action for Manning Publications. He is also an avid photographer and jazz drummer. Ken is a DZone MVB and is not an employee of DZone and has posted 35 posts at DZone. You can read more from them at their website. View Full User Profile

Spock and Roo: Easier Add-on Testing, Part 2

06.03.2012
| 1649 views |
  • submit to reddit

Moving on to some more interesting tests. Given this method:

public boolean isInstalljQueryCommandAvailable() {
    String jsLocation = pathResolver.getFocusedIdentifier(
        Path.SRC_MAIN_WEBAPP, "/js");

    return fileManager.findMatchingAntPath(
        jsLocation + "**/jquery-1.*.min.js").isEmpty();
  }

I want to use Spock to test it. The challenge is the somewhat more nested set of objects. My add-on extends the AbstractOperations class (to get the embedded fileManager), so I need to mock that, plus mock the path resolver I've mounted with @Reference in my add-on as well.

To set it up I do this:

class JqueryuiOperationsImplTest extends spock.lang.Specification {

    JqueryuiOperationsImpl operations;

    def setup() {
        operations = new JqueryuiOperationsImpl();

        operations.pathResolver = Mock(PathResolver);
        operations.fileManager = Mock(FileManager);
    }

Spock mocks are similar to EasyMock, in that we then detail our assertions of what should happen before the test runs. In fact, based on a really interesting thread I found this AM while banging my head against the wall (don't do that, it hurts), if you put any mocking assertions in the when: part of a Spock test, it moves them to the setup: block. Anyway, here is my set of assertions:

def "isJqueryInstallAvailable called and happy path"() {

    setup:
    1* operations.pathResolver.getFocusedIdentifier(
            _, _) >> "src/main/webapp/js"

    1* operations.fileManager.findMatchingAntPath(
            _ as String) >> new TreeSet<FileDetails>()

I'm using Spock's matchers to eat the expressions - I don't really care what we pass to the getFocusedIdentifier or findMatchingAntPath methods, I just want them mocked and I want them to return values.

The >> is what tells us that we're stubbing the return output.

Here is the full test:

def "isJqueryInstallAvailable called and happy path"() {
    setup:
    1* operations.pathResolver.getFocusedIdentifier(
            _, _) >> "src/main/webapp/js"

    1* operations.fileManager.findMatchingAntPath(
            _ as String) >> new TreeSet<FileDetails>()

    when:
    def result = operations.isInstalljQueryCommandAvailable();

    then:
    result == true
}

Don't do what I did to get my head bruised. I originally wrote this:

1* operations.fileManager.findMatchingAntPath(
                _ as String).empty() >> false

I got my brain mixed up because I saw the line:

return fileManager.findMatchingAntPath(
    jsLocation + "**/jquery-1.*.min.js").isEmpty();

And that's going to throw a tasty NullPointerException because you're mocking the return of the method in fileManager, not the return statement! Oh, bother.

 

 

 

 

 

 

 

Published at DZone with permission of Ken Rimple, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Daniel Slazer replied on Tue, 2012/06/12 - 12:06pm

The simplest way to know that is to send something with a teminating character and then look at the characters you receive.

You can do that with code similar to the code you posted but why did you post code that can't work?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.