编译器说,公共groovy方法必须是公共的

编译器说,公共groovy方法必须是公共的,groovy,traits,spock,grails-3.3,Groovy,Traits,Spock,Grails 3.3,此错误的原因是什么,如何修复 乍一看,这似乎是groovy编译器中的一个缺陷 :compileIntegrationTestGroovystartup failed: C:\src\my-project\src\integration-test\groovy\my\project\MyServiceISpec.groovy: 31: The method setup should be public as it implements the corresponding method from i

此错误的原因是什么,如何修复

乍一看,这似乎是groovy编译器中的一个缺陷

:compileIntegrationTestGroovystartup failed:
C:\src\my-project\src\integration-test\groovy\my\project\MyServiceISpec.groovy: 31: The method setup should be public as it implements the corresponding method from interface my.project.MyTrait
. At [31:5]  @ line 31, column 5.
       public void setup() {
       ^

1 error
我的grails集成测试如下所示:

@Integration
@Rollback
class MyServiceISpec extends Specification implements MyTrait {
    @Autowired
    MyService service

    OtherService otherService = Mock()

    public void setup() {
        myTraithMethod()
        service.otherService = otherService
    }
}
trait MyTrait {
    public void setup() {
        myTraithMethod()
    }

    private myTraitMethod() {
        ...
    }
}
@Integration
@Rollback
class MyServiceISpec extends Specification implements MyTrait {
    @Autowired
    MyService service
    OtherService otherService = Mock()

    void setup() {
        service.otherService = otherService
        traitSetup()
    }

    def 'some test here'() {
        ...
    }
}

trait MyTrait {
    void traitSetup() {
        myTraitMethod()
    }

    private myTraitMethod() {
        ...
    }
}
我的特点是:

@Integration
@Rollback
class MyServiceISpec extends Specification implements MyTrait {
    @Autowired
    MyService service

    OtherService otherService = Mock()

    public void setup() {
        myTraithMethod()
        service.otherService = otherService
    }
}
trait MyTrait {
    public void setup() {
        myTraithMethod()
    }

    private myTraitMethod() {
        ...
    }
}
@Integration
@Rollback
class MyServiceISpec extends Specification implements MyTrait {
    @Autowired
    MyService service
    OtherService otherService = Mock()

    void setup() {
        service.otherService = otherService
        traitSetup()
    }

    def 'some test here'() {
        ...
    }
}

trait MyTrait {
    void traitSetup() {
        myTraitMethod()
    }

    private myTraitMethod() {
        ...
    }
}

Update在trait setup方法中添加了
public
关键字。

1/不确定,但是trait名称是ResetsDatabase,您的测试实现了MyTrait。 可能是某些特征的混淆?
2/在我看来,如果您的trait表示该方法(此处的设置)是私有的,那么在实现的方法上就不能有公共方法。

1/不确定,但是trait名称是ResetsDatabase,并且您的测试实现了MyTrait。 可能是某些特征的混淆?
2/在我看来,如果您的特性表明该方法(此处设置)是私有的,那么在实现的方法上就不可能有公共方法。

我认为该问题的根源是AST,因为Spock使用AST转换并编译规范。你可以在这里阅读:

特征与AST转换不正式兼容。一些 它们,比如@CompileStatic,将应用于trait本身(而不是trait本身) 实现类),而其他类将应用于 实施类与特质。绝对没有保证 AST转换将在特征上运行,就像在常规特征上运行一样 类,因此使用它的风险自负

您可以通过重命名traitSetup()上trait中的
setup()
方法来解决此问题,例如,从规范
setup()
方法调用它,如下所示:

@Integration
@Rollback
class MyServiceISpec extends Specification implements MyTrait {
    @Autowired
    MyService service

    OtherService otherService = Mock()

    public void setup() {
        myTraithMethod()
        service.otherService = otherService
    }
}
trait MyTrait {
    public void setup() {
        myTraithMethod()
    }

    private myTraitMethod() {
        ...
    }
}
@Integration
@Rollback
class MyServiceISpec extends Specification implements MyTrait {
    @Autowired
    MyService service
    OtherService otherService = Mock()

    void setup() {
        service.otherService = otherService
        traitSetup()
    }

    def 'some test here'() {
        ...
    }
}

trait MyTrait {
    void traitSetup() {
        myTraitMethod()
    }

    private myTraitMethod() {
        ...
    }
}

我认为这个问题的根源是AST,因为Spock使用AST转换并编译规范。你可以在这里阅读:

特征与AST转换不正式兼容。一些 它们,比如@CompileStatic,将应用于trait本身(而不是trait本身) 实现类),而其他类将应用于 实施类与特质。绝对没有保证 AST转换将在特征上运行,就像在常规特征上运行一样 类,因此使用它的风险自负

您可以通过重命名traitSetup()上trait中的
setup()
方法来解决此问题,例如,从规范
setup()
方法调用它,如下所示:

@Integration
@Rollback
class MyServiceISpec extends Specification implements MyTrait {
    @Autowired
    MyService service

    OtherService otherService = Mock()

    public void setup() {
        myTraithMethod()
        service.otherService = otherService
    }
}
trait MyTrait {
    public void setup() {
        myTraithMethod()
    }

    private myTraitMethod() {
        ...
    }
}
@Integration
@Rollback
class MyServiceISpec extends Specification implements MyTrait {
    @Autowired
    MyService service
    OtherService otherService = Mock()

    void setup() {
        service.otherService = otherService
        traitSetup()
    }

    def 'some test here'() {
        ...
    }
}

trait MyTrait {
    void traitSetup() {
        myTraitMethod()
    }

    private myTraitMethod() {
        ...
    }
}

Grails版本:3.3.4,groovy版本:2.4.7,java 8,gradle 3.5Grails版本:3.3.4,groovy版本:2.4.7,java 8,gradle 3.5Fixed#1(这是为发布清理代码的一个工件)。感谢您指出这一点。在trait中的方法声明中添加了
public
关键字,但没有任何效果。修复了#1(这是为发布而清理代码的工件)。感谢您指出。在trait中的方法声明中添加了
public
关键字,但这没有任何效果。这是正确的,traits中不能有spock特殊方法。这是正确的,traits中不能有spock特殊方法。