Skip to content

Instantly share code, notes, and snippets.

@schultzisaiah
Last active July 9, 2025 21:30
Show Gist options
  • Select an option

  • Save schultzisaiah/64f26656bc5a447e91cac078ba08aada to your computer and use it in GitHub Desktop.

Select an option

Save schultzisaiah/64f26656bc5a447e91cac078ba08aada to your computer and use it in GitHub Desktop.
TestMe (IntelliJ Plugin) macro for Mockito-free Spock tests
#parse("TestMe macros.groovy")
#set($mockableFields = [])
#foreach($field in $TESTED_CLASS.fields)
#if($MockitoMockBuilder.isMockable($field, $TESTED_CLASS))
#set($devNull = $mockableFields.add($field))
#end
#end
#set($hasMocks = !$mockableFields.isEmpty())
#if($PACKAGE_NAME)
package ${PACKAGE_NAME}
#end
import spock.lang.Specification
#parse("File Header.java")
@SuppressWarnings('GroovyAccessibility')
// TODO: Rename the file from "_Test.groovy" to "_Spec.groovy" to follow Spock conventions.
class ${TESTED_CLASS.name}Spec extends Specification {
#foreach($field in $mockableFields)
private $field.type.canonicalName mock${StringUtils.capitalizeFirstLetter($field.name)}
#end
private ${TESTED_CLASS.canonicalName} testMe
def setup() {
#foreach($field in $mockableFields)
mock${StringUtils.capitalizeFirstLetter($field.name)} = Mock()
#end
testMe = new ${TESTED_CLASS.canonicalName}(
#foreach($field in $mockableFields)
mock${StringUtils.capitalizeFirstLetter($field.name)}#if($foreach.hasNext), #end
#end
)
}
#foreach($method in $TESTED_CLASS.methods)
#*
Custom logic to determine if a method should be tested.
This now includes private methods but excludes inherited methods.
*#
#set($isFromTestedClass = $method.getOwnerClassCanonicalType() == $TESTED_CLASS.getCanonicalName())
#set($isConstructor = $method.isConstructor())
#set($isAbstract = $method.hasModifier('abstract'))
#set($isSynthetic = $method.isSynthetic())
#set($isGetter = false)
#if( (($method.name.startsWith('get') && $method.name.length() > 3) || ($method.name.startsWith('is') && $method.name.length() > 2)) && $method.methodParams.isEmpty() && $method.returnType.name != 'void' )
#set($isGetter = true)
#end
#set($isSetter = false)
#if( $method.name.startsWith('set') && $method.name.length() > 3 && $method.methodParams.size() == 1 && $method.returnType.name == 'void' )
#set($isSetter = true)
#end
#if($isFromTestedClass && !$isConstructor && !$isGetter && !$isSetter && !$isAbstract && !$isSynthetic)
def "test #renderTestMethodNameAsWords($method.name)"() {
given:
#foreach($param in $method.methodParams)
def mock${StringUtils.capitalizeFirstLetter($param.name)} = Mock($param.type.canonicalName)
#end
// TODO: Stub any necessary mock methods here.
// Example: mockSomeDependency.someMethod(_) >> "someValue"
when:
#if($method.returnType && $method.returnType.name != "void")def result = #end#if($method.static)${TESTED_CLASS.name}#{else}testMe#end.${method.name}(#foreach($param in $method.methodParams)mock${StringUtils.capitalizeFirstLetter($param.name)}#if($foreach.hasNext), #end#end)
then:
false // TODO: validate result
}
#end
#end
}
@schultzisaiah
Copy link
Author

In the TestMe settings window, create a new Test Class named "SPOCK" (or whatever you prefer) using the extension groovy and the macro above.

image

@schultzisaiah
Copy link
Author

What this script produces is far from perfect or runnable. However, it's a super useful starting place to help combat the "Blank Page Syndrome" that can happen when writing tests from scratch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment