如果我使用的条款不正确,我必须先道歉。我只使用groovy / java进行自动化任务(Gradle),而且我不具备多年提供生产级软件的经验。
所以,我所面临的挑战如下:我有一个规范试图测试返回字符串是否符合预期(几乎与this相同)。
def "pretty print returns correct string"() {
setup:
X509Certificate stubCert = Stub()
stubCert.getSubjectDN().toString() >> "Test"
when:
def output = X509CertificateUtils.prettyPrint(stubCert)
then:
output == "Subject: Test"
}
然而,区别在于我的方法约束返回一个Principal对象,而它的对象是toString(),我真的想要存根。我以为我在上面做的正确,但它没有给出我期望的结果。
这是我的帮助班。
import java.security.cert.X509Certificate
class X509CertificateUtils {
static def prettyPrint(X509Certificate x509Certificate) {
return "Subject: ${x509Certificate.getSubjectDN()}"
}
}
如果我运行此测试,则会收到以下错误:
output == "Subject: Test"
| |
| false
| 38 differences (20% similarity)
| Subject: (Mock for )t(ype 'Principal' named 'dummy')
| Subject: (Tes------)t(-----------------------------)
Subject: Mock for type 'Principal' named 'dummy'
感谢任何帮助。
答案 0 :(得分:6)
只需创建第二个存根:
X509Certificate stubCert = Stub()
Principal princ = Stub()
princ.toString() >> "Test"
stubCert.getSubjectDN() >> princ
答案 1 :(得分:3)
Spock有一些伪造物体的方法。这是current documentation。
我的问题...你是否试图测试prettyPrint()单独工作正常,SubjectDN.toString()打印正确,还是两者的组合?我的建议是让你的mock返回一个实际的SubjectDN()对象,然后你也可以测试它。没有更多的工作,如果出现问题,你可以更好地了解问题的起源。 Max的解决方案将解决您的问题;我没有仔细阅读或遵循良好的测试范围实践。我会把剩下的答案留作思考。如果你想将Max的stub方法与我的参数化混合,我建议将where块中的所需字符串传递给setup块中的stub创建。
这开始脱离主题,但是如果你需要测试多个SubjectDN场景(null,empty,各种大写,数字等);你也应该考虑参数化你的测试。
def "pretty print returns correct string"() {
setup:
X509Certificate stubCert = Mock()
stubCert.getSubjectDN() >> subject
expect:
subject.toString() == expectedToString
X509CertificateUtils.prettyPrint(stubCert) == expectedFormatted
where:
subject | expectedToString | expectedFormatted
new SubjectDN("") | ???? | "Subject: ????"
new SubjectDN(null) | ???? | "Subject: ????"
new SubjectDN("test") | "test" | "Subject: Test"
new SubjectDN("testing") | "testing" | "Subject: Testing"
}
如果您的漂亮打印真的像预先“主题:”一样简单,您可能会计算出您的预期格式变量;但是你真的不应该让你的测试模仿你正在测试的代码,以便更容易进行测试。
我还发现,当迭代具有流体长度时,参数化测试的表格式会变得混乱或难以维护。我的偏好是制作一个地图列表,每个地图代表一次测试迭代。它将每个测试迭代捆绑在一起,让不熟悉的开发人员更好地了解每次迭代测试的内容。
@Unroll(iteration.testName) // Shows each iteration in its own result (in most IDEs)
def "testing printing of a SubjectDN"() {
setup:
X509Certificate stubCert = Mock()
stubCert.getSubjectDN() >> iteration.subject
expect:
subject.toString() == iteration.expectedToString
X509CertificateUtils.prettyPrint(stubCert) == expectedFormatted
where:
iteration << [
[testName: "Testing pretty printing a normal SubjectDN",
subject: new SubjectDN("test"),
expectedToString: "test"],
[testName: "Testing pretty printing a normal SubjectDN",
subject: new SubjectDN("testing 123"),
expectedToString: "testing 123"],
[testName: "Testing pretty printing a null SubjectDN",
subject: new SubjectDN(null),
expectedToString: ????]
// And so on...
]
expectedFormatted = "Subject: ${iteration.expectedToString}"
}