1 回答
TA贡献1785条经验 获得超4个赞
您在这里处理签名的 JAR。假设您不想全局禁用 Java 的安全功能,也不想创建所有 BouncyCastle JAR 的副本,删除它们的清单,我将向您展示一个解决方法。
问题是 Spock 模拟(也有其他)是在与原始类相同的包中创建的。但是模拟是未签名的代码,因此是错误消息。现在,您可以只对要模拟的类进行子类化并改为模拟该子类。如果您在测试中的任何地方需要它们,只需确保子类具有来自其父类的所有必要构造函数。
package de.scrum_master.stackoverflow;
import org.bouncycastle.cms.SignerInformation;
public class SignerInformationConsumer {
public String interact(SignerInformation si) {
return si.getDigestAlgOID();
}
}
package de.scrum_master.stackoverflow
import org.bouncycastle.cms.SignerInformation
import spock.lang.Specification
class SignerInformationConsumerTest extends Specification {
static class SignerInformationMock extends SignerInformation {
protected SignerInformationMock(SignerInformation baseInfo) {
super(baseInfo)
}
}
//SignerInformation signerInformation = Spy(SignerInformationMock, useObjenesis: true)
SignerInformation signerInformation = Mock(SignerInformationMock)
def "should return valid array"() {
given:
SignerInformationConsumer signerInformationConsumer = new SignerInformationConsumer()
signerInformation.getDigestAlgOID() >> "aaa"
expect:
signerInformationConsumer.interact(signerInformation) == "aaa"
}
}
关于您的测试的几句话:
不要使用,@Shared因为测试应该相互独立。您可以将特性方法 A 的副作用转移到 B。共享变量应该只在非常罕见的情况下使用,例如,如果您创建的对象在时间或资源方面非常昂贵。模拟肯定不是。因此,要么在您的功能方法中创建模拟,要么,如果其他功能方法要使用相同的模拟定义,请使用不带@Shared. 当然,您可以忽略此建议,但我仍然认为您应该遵循它。
您的测试不测试应用程序,它只测试模拟。我希望你的真实测试用例看起来不同,因为这个测试,即使我让它为你工作,也只检查存根结果是否与测试开始时指定的一样。
我的代码中的注释行向您展示了如果出于任何原因需要(例如,您想使用真实对象并仅存根一个或几个方法),您可以如何使用间谍而不是模拟。在这种特殊情况下,您将需要 Objenesis 作为依赖项,否则您将收到异常,因为没有默认构造函数。或者,您必须创建 spy 并包含构造函数参数。
如果getDigestAlgOID()要在每个特征方法中以相同的方式存根,您可以将存根部分从特征方法移动到模拟定义中,如下所示:
SignerInformation signerInformation = Mock(SignerInformationMock) {
getDigestAlgOID() >> "aaa"
}
添加回答
举报