0

I have a project where I've split up my logic into multiple gradle files and written them into the ext{} block. Here's a simplified version of what I'm doing to illustrate my issue:

build.gradle:

plugins {
    id 'groovy'
}

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.3.11'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

buildSrc/src/main/resources/testJson.json:

{
  "dogs": [
    {
      "name": "chip",
      "id": 1
    },
    {
      "name": "spot",
      "id": 2
    }
  ]
}

buildSrc/src/main/scripts/parseDogs.gradle:

import groovy.json.JsonSlurper

configure(project.rootProject) {
    ext.parseDogs = { ->

        def json = new JsonSlurper().parseText(file('src/main/resources/testJson.json').text)

        def names = []
        json.dogs.each { dog ->
            names.add(dog.name)
        }

        names
    }
}

Here's what I have related to my test:

buildSrc/build.gradle:

plugins {
    id 'groovy'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.spockframework:spock-core:2.0-groovy-2.5'
    testImplementation 'org.codehaus.groovy:groovy-all:2.5.4'
}

test {
    useJUnitPlatform()
}

buildSrc/src/test/groovy/ExampleTest.groovy:

import spock.lang.Specification

class ExampleTest extends Specification{

    // passes
    def "should be a simple assertion"() {
        expect:
        1 == 1
    }

    // fails
    def "get dog names"() {
        given:
        GroovyShell shell = new GroovyShell()
        def getDogNames = shell.parse(new File('src/main/scripts/parseDogs.gradle'))

        expect:
        getDogNames().size() == 2
    }

}

When I try to build locally, I get the error:

ExampleTest > get dog names FAILED
    org.spockframework.runtime.ConditionFailedWithExceptionError at ExampleTest.groovy:15
        Caused by: groovy.lang.MissingMethodException at ExampleTest.groovy:15

The report generated under buildSrc/build/reports/tests/test has a similar message:

Condition failed with Exception:

getDogNames().size() == 2
|
groovy.lang.MissingMethodException: No signature of method: parseDogs.call() is applicable for argument types: () values: []
Possible solutions: wait(), any(), wait(long), main([Ljava.lang.String;), tap(groovy.lang.Closure), each(groovy.lang.Closure)
    at ExampleTest.get dog names(ExampleTest.groovy:15)

    at ExampleTest.get dog names(ExampleTest.groovy:15)
Caused by: groovy.lang.MissingMethodException: No signature of method: parseDogs.call() is applicable for argument types: () values: []
Possible solutions: wait(), any(), wait(long), main([Ljava.lang.String;), tap(groovy.lang.Closure), each(groovy.lang.Closure)
    ... 1 more

Is there a way I can access the ext.parseDogs() method in my test?

Sam Jones
  • 43
  • 5
  • 1
    You can't parse Gradle files with GroovyShell. Why not put your `testJson.json` in `src/test/resources`, then move the parseDogs method into a test class? – tim_yates Jul 07 '21 at 07:40
  • @tim_yates The code I gave was just a sample to mirror my work project - I have to have the code under the buildSrc folder in order for gradle to recognize my other scripts and groovy classes. You're right that I can move the parseDogs method into a class but my project currently has a lot of logic written across many files in the ext{} block, that's why I'm trying to find a way to write tests without redo-ing everything! – Sam Jones Jul 07 '21 at 08:06
  • Think you may have to use testkit if you need to test the build itself https://docs.gradle.org/current/userguide/test_kit.html#test_kit – tim_yates Jul 07 '21 at 08:15

0 Answers0