从Spock运行空手道(1.0.1)测试时,在模拟中设置的系统属性在Karate.properties[';message';]中未定义

从Spock运行空手道(1.0.1)测试时,在模拟中设置的系统属性在Karate.properties[';message';]中未定义,karate,spock,Karate,Spock,在空手道版本0.9.5中,我能够在模拟调用期间使用System.setProperty('message',message')。然后,该属性在使用karate.properties['message']的功能中可用。我已经升级到1.0.1版,现在是空手道的结果。属性['message']导致未定义 斯波克测试代码 @SpringBootTest(webEnvironment=SpringBootTest.webEnvironment.RANDOM\u端口) 类ApiTestRunnerSpec扩

在空手道版本0.9.5中,我能够在模拟调用期间使用System.setProperty('message',message')。然后,该属性在使用karate.properties['message']的功能中可用。我已经升级到1.0.1版,现在是空手道的结果。属性['message']导致未定义

斯波克测试代码

@SpringBootTest(webEnvironment=SpringBootTest.webEnvironment.RANDOM\u端口)
类ApiTestRunnerSpec扩展了规范{
@本地服务器端口
专用int端口
@春豆
MessageLogger MessageLogger=Mock()
def“设置”(){
System.out.println(“在端口上运行:”+端口)
System.setProperty(“服务器.端口”,“端口+端口”)
}
def“运行模拟ApiTest”(){
鉴于:
System.setProperty('foo','bar')
什么时候:
Results=Runner.path(“classpath:”).tags(“~@ignore”).parallel(5)
然后:
结果!=null
1*messageLogger.logMessage(u作为字符串)>>{String message->
断言消息!=null
System.setProperty(“消息”,消息)
}
}
}
控制器

@RestController
公共类消息控制器{
@自动连线私人信息记录器;
@GetMapping(“/message”)
公共字符串消息(){
String message=“重要消息”;
logMessage(消息);
返回消息;
}
}
消息记录器

@组件
公共类消息记录器{
公共无效日志消息(字符串消息){
System.out.println(消息);
}
}
karate-config.js

函数fn(){
空手道。配置('connectTimeout',10000);
空手道。配置('readTimeout',10000);
karate.configure('ssl',true);
变量配置={
localUrl:'http://localhost:'+java.lang.System.getProperty('server.port'),
};
打印('localUrl:config.localUrl:';
返回配置;
}
特征

@mockMessage
@parallel=true
Feature: Test Message

  Background:
    * url localUrl

  Scenario: GET

  Given path '/message'
  When method get
  Then status 200

  * print 'foo value ' + karate.properties['foo']
  * print 'message value ' + karate.properties['message']
0.9.5

2021-04-28 15:07:51.819(…)[print]**foo值条**
2021-04-28 15:07:51.826(…)[打印]**消息值重要消息**
1.0.1

2021-04-28 14:36:58.566(…)[打印]**foo值条**
2021-04-28 14:36:58.580(…)[打印]**消息值未定义**

我克隆了您的项目,并注意到一些过时的东西(Groovy、Spock和GMaven+版本)。升级它们并没有改变结果,我仍然可以重现你的问题

A还注意到,在您的两个分支中,POM的不同不仅仅在于空手道版本号,还在于依赖关系的不同。如果我使用1.0.1分支中的测试,那么测试在0.9.5下就不再工作了。因此,我为您的项目提供了分支,并为每个分支发送了两个pull请求,两个版本的依赖项设置都是相同的。现在,分支实际上只是空手道版本号不同:

顺便说一句,由于某种原因,我不得不编译运行JDK11的代码,JDK16不起作用。GMaven+抱怨Java 16 groovy类文件(字节码版本60.0),尽管GMaven+应该使用目标级别11。不知道这是怎么回事。无论如何,在Java11上,我可以重现您的问题。由于两个分支的斯波克版本是相同的,我想问题在于空手道本身。我建议在那里打开一个问题,链接到您的GitHub项目(在您接受我的PRs之后)。斯波克明确地设置了系统属性,我在存根闭包顺序中添加了更多的日志输出来验证这一点。也许这是一个关于空手道如何以及何时与斯波克交流的问题


更新:Peter Thomas在回答中建议将要传输到功能的值存储在Java对象中,并在Spock测试设置后从功能访问该值。我猜,他的意思是这样的:

@SpringBootTest(webEnvironment=SpringBootTest.webEnvironment.RANDOM\u端口)
类ApiTestRunnerSpec扩展了规范{
@本地服务器端口
专用int端口
@春豆
MessageLogger MessageLogger=Mock(){
1*日志消息(u作为字符串)>>{String消息->
断言消息!=null
MessageHolder.INSTANCE.message=消息
}
}
def“设置”(){
System.out.println(“在端口上运行:”+端口)
System.setProperty(“服务器.端口”,“端口+端口”)
}
def“运行模拟ApiTest”(){
鉴于:
结果=跑步者
.path(“类路径:”)
.systemProperty(“foo”、“bar”)
.tags(“~@忽略”)
.平行(5)
期望:
结果
}
静态类消息持有者{
public static final MessageHolder实例=new MessageHolder()
私有字符串消息
私有消息持有者(){}
字符串getMessage(){
回信
}
void setMessage(字符串消息){
this.message=消息
}
}
}
@mockMessage
@平行=真
功能:测试消息
背景:
*url本地url
场景:获取
给定路径“/消息”
当方法得到
然后状态200
*打印'foo value'+karate.properties['foo']
*def getMessage=
"""
函数(){
var MessageHolder=Java.type('com.example.spock.karate.ApiTestRunnerSpec.MessageHolder');
return MessageHolder.INSTANCE.getMessage();
}
"""
*def message=调用getMessage{}
*打印“消息值”+消息

更新2:这是Peter的第二个想法的实现,即通过JS访问Java系统属性。因此,我简化了使用消息持有者单例的工作,但不必要的复杂版本,再次消除了它:

现在看起来就像这样(与最初的Spock规范类似,只是经过重构,没有那么详细):

@SpringBoot
Results results = Runner.path("classpath:")
    .systemProperty("foo", "bar")
    .tags("~@ignore").parallel(5)