nu.studer.credentials 在 Spock 内部不起作用
nu.studer.credentials does not work from inside Spock
我正在构建一个 Gradle 插件,它需要用户名和密码才能访问外部资源;为了避免使用明文密码,我使用插件 nu.studer.credentials
.
为了测试我的插件,我使用了 Spock;以下测试文件 CredentialsFunctionTest.groovy
被剥离为仅相关部分,以显示问题:
package my.gradle.plugin
import org.gradle.testkit.runner.GradleRunner
import spock.lang.Specification
import spock.lang.TempDir
/**
* A simple functional test for the credentials acquisition.
*/
class CredentialsFunctionalTest extends Specification {
@TempDir
private File projectDir
private getBuildFile() {
new File( projectDir, "build.gradle" )
}
private getSettingsFile() {
new File( projectDir, "settings.gradle" )
}
def "can run task"() {
given:
//---> Begin of settings file <------------------------------------------------
settingsFile << """
plugins {
id 'nu.studer.credentials' version '3.0'
}
"""
//---> End of settings file <--------------------------------------------------
//---> Begin of build file <---------------------------------------------------
buildFile << """
plugins {
id 'nu.studer.credentials'
}
String username = credentials.forKey( 'myUser' )
System.out.printf( 'Username: %s%n', username )
String password = credentials.forKey( 'myPassword' )
System.out.printf( 'Password: %s%n', password )
task doSomething {
}
"""
//---> End of build file <-----------------------------------------------------
when:
def runner = GradleRunner.create()
runner.forwardOutput()
runner.withPluginClasspath()
runner.withArguments("doSomething" )
runner.withProjectDir( projectDir )
def result = runner.build()
then:
result.output.contains( "Alive!" )
}
}
“用户名”和“密码”的输出是 null
– 这样的测试失败是预料之中的,因为字符串 "Alive!"
的任何地方都没有输出。
当我将文件 settings.gradle
和 build.gradle
(下面的内容)放置到一个空文件夹中,并使用 gradle doSomething
调用 gradle 时,我得到了预期的输出。
settings.gradle
:
plugins {
id 'nu.studer.credentials' version '3.0'
}
build.gradle
:
plugins {
id 'nu.studer.credentials'
}
String username = credentials.forKey( 'myUser' )
System.out.printf( 'Username: %s%n', username )
String password = credentials.forKey( 'myPassword' )
System.out.printf( 'Password: %s%n', password )
task doSomething {
}
nu.studer.credentials
插件将值存储在 $GRADLE_USER_HOME/gradle.encrypted.properties
中,因此一个假设是 Spock 使用不同的临时用户 and/or 主文件夹。
根据 Leonard Brünings 在他对我的问题的评论中给我的提示,我能够确定问题并制定解决方案。
正如伦纳德所说,问题不在于 Spock 本身,而在于执行测试的 GradleRunner
:这将使用与 [= 不同的“Gradle 用户主目录” 32=] Gradle 执行.
使用参数-g
或--gradle-user-home
,可以更改,但不建议在测试Gradle插件时使用此指向默认位置(我们正在使用 Gradle 来测试 Gradle ……)。
幸运的是,nu.studer.credentials
插件提供了一个配置参数,允许指定保存加密凭据的文件的位置:-PcredentialsLocation=<path>
.
所以解决方案看起来像这样(我只从原始测试脚本中提取了 when:
部分):
…
when:
def runner = GradleRunner.create()
runner.forwardOutput()
runner.withPluginClasspath()
runner.withArguments( "-PcredentialsLocation=%s/.gradle".formatted( System.getProperty( "user.home" ) ), "doSomething" )
runner.withProjectDir( projectDir )
def result = runner.build()
…
当然,测试仍然失败,但它现在显示 username
和 password
!
的正确值
我正在构建一个 Gradle 插件,它需要用户名和密码才能访问外部资源;为了避免使用明文密码,我使用插件 nu.studer.credentials
.
为了测试我的插件,我使用了 Spock;以下测试文件 CredentialsFunctionTest.groovy
被剥离为仅相关部分,以显示问题:
package my.gradle.plugin
import org.gradle.testkit.runner.GradleRunner
import spock.lang.Specification
import spock.lang.TempDir
/**
* A simple functional test for the credentials acquisition.
*/
class CredentialsFunctionalTest extends Specification {
@TempDir
private File projectDir
private getBuildFile() {
new File( projectDir, "build.gradle" )
}
private getSettingsFile() {
new File( projectDir, "settings.gradle" )
}
def "can run task"() {
given:
//---> Begin of settings file <------------------------------------------------
settingsFile << """
plugins {
id 'nu.studer.credentials' version '3.0'
}
"""
//---> End of settings file <--------------------------------------------------
//---> Begin of build file <---------------------------------------------------
buildFile << """
plugins {
id 'nu.studer.credentials'
}
String username = credentials.forKey( 'myUser' )
System.out.printf( 'Username: %s%n', username )
String password = credentials.forKey( 'myPassword' )
System.out.printf( 'Password: %s%n', password )
task doSomething {
}
"""
//---> End of build file <-----------------------------------------------------
when:
def runner = GradleRunner.create()
runner.forwardOutput()
runner.withPluginClasspath()
runner.withArguments("doSomething" )
runner.withProjectDir( projectDir )
def result = runner.build()
then:
result.output.contains( "Alive!" )
}
}
“用户名”和“密码”的输出是 null
– 这样的测试失败是预料之中的,因为字符串 "Alive!"
的任何地方都没有输出。
当我将文件 settings.gradle
和 build.gradle
(下面的内容)放置到一个空文件夹中,并使用 gradle doSomething
调用 gradle 时,我得到了预期的输出。
settings.gradle
:
plugins {
id 'nu.studer.credentials' version '3.0'
}
build.gradle
:
plugins {
id 'nu.studer.credentials'
}
String username = credentials.forKey( 'myUser' )
System.out.printf( 'Username: %s%n', username )
String password = credentials.forKey( 'myPassword' )
System.out.printf( 'Password: %s%n', password )
task doSomething {
}
nu.studer.credentials
插件将值存储在 $GRADLE_USER_HOME/gradle.encrypted.properties
中,因此一个假设是 Spock 使用不同的临时用户 and/or 主文件夹。
根据 Leonard Brünings 在他对我的问题的评论中给我的提示,我能够确定问题并制定解决方案。
正如伦纳德所说,问题不在于 Spock 本身,而在于执行测试的 GradleRunner
:这将使用与 [= 不同的“Gradle 用户主目录” 32=] Gradle 执行.
使用参数-g
或--gradle-user-home
,可以更改,但不建议在测试Gradle插件时使用此指向默认位置(我们正在使用 Gradle 来测试 Gradle ……)。
幸运的是,nu.studer.credentials
插件提供了一个配置参数,允许指定保存加密凭据的文件的位置:-PcredentialsLocation=<path>
.
所以解决方案看起来像这样(我只从原始测试脚本中提取了 when:
部分):
…
when:
def runner = GradleRunner.create()
runner.forwardOutput()
runner.withPluginClasspath()
runner.withArguments( "-PcredentialsLocation=%s/.gradle".formatted( System.getProperty( "user.home" ) ), "doSomething" )
runner.withProjectDir( projectDir )
def result = runner.build()
…
当然,测试仍然失败,但它现在显示 username
和 password
!