如何在 Spock 中模拟 class 的单个方法?
How to mock a single method for a class in Spock?
我正在尝试测试 class 中的如下方法:
class SomeHelper {
ByteArrayOutputStream fooBar (Request request) {
ByteArrayOutputStream baos = someParser.parseData(getRequestFileInputStream(request.filename))
return baos
}
InputStream getRequestFileInputStream(String filename) {
//return intputStream of object from S3
}
....
}
在上面,getRequestFileInputStream
是一个以文件名作为参数的方法。它从 AWS S3 获取该文件的输入流。在测试 Spock 的 fooBar
方法时,我想为 getRequestFileInputStream
方法提供一个模拟,因为我不想使用 class 中的此方法的实现,因为它转到另一个存储桶名称。
这可以吗?
下面是我试过的:
class SomeHelperSpec extends Specification{
//this is the implementation of getRequestFileInputStream I want to use while testing
InputStream getObjectFromS3(String objectName) {
def env = System.getenv()
AwsClientBuilder.EndpointConfiguration endpoint = new AwsClientBuilder.EndpointConfiguration(env["endpoint_url"], env["region_name"])
AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard()
builder.setEndpointConfiguration(endpoint)
builder.setCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(env["ACCESS_KEY"], env["SECRET_KEY"])))
AmazonS3 s3 = builder.build()
return s3.getObject("testbucket", objectName).getObjectContent()
}
def "test fooBar" () {
given:
someHelper = new SomeHelper()
someHelper.getRequestFileInputStream(_) >> getObjectFromS3(fileName)
someHelper.someParser = Mock(SomeParser) {
....
}
Request requestInstance = new Request()
request.filename = fileName
request.fileType = fileType
expect:
someHelper.fooBar(requestInstance).getText == returnVal
where:
fileType | fileName | returnVal
"PDF" | "somepdf.pdf" | "somereturnval"
}
}
但是,上面的方法不起作用,因为它仍在尝试调用 SomeHelper
中 getRequestFileInputStream
的原始实现,而不是使用规范中提供的模拟实现。
你可以使用间谍
def someHelper = Spy(SomeHelper)
someHelper.getRequestFileInputStream(_) >> getObjectFromS3(fileName)
见Spies。
您可以使用真实的对象,但使用重写的方法:
given:
someHelper = new SomeHelper() {
@Override
InputStream getRequestFileInputStream(String filename) {
return getObjectFromS3(fileName)
}
}
我正在尝试测试 class 中的如下方法:
class SomeHelper {
ByteArrayOutputStream fooBar (Request request) {
ByteArrayOutputStream baos = someParser.parseData(getRequestFileInputStream(request.filename))
return baos
}
InputStream getRequestFileInputStream(String filename) {
//return intputStream of object from S3
}
....
}
在上面,getRequestFileInputStream
是一个以文件名作为参数的方法。它从 AWS S3 获取该文件的输入流。在测试 Spock 的 fooBar
方法时,我想为 getRequestFileInputStream
方法提供一个模拟,因为我不想使用 class 中的此方法的实现,因为它转到另一个存储桶名称。
这可以吗?
下面是我试过的:
class SomeHelperSpec extends Specification{
//this is the implementation of getRequestFileInputStream I want to use while testing
InputStream getObjectFromS3(String objectName) {
def env = System.getenv()
AwsClientBuilder.EndpointConfiguration endpoint = new AwsClientBuilder.EndpointConfiguration(env["endpoint_url"], env["region_name"])
AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard()
builder.setEndpointConfiguration(endpoint)
builder.setCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(env["ACCESS_KEY"], env["SECRET_KEY"])))
AmazonS3 s3 = builder.build()
return s3.getObject("testbucket", objectName).getObjectContent()
}
def "test fooBar" () {
given:
someHelper = new SomeHelper()
someHelper.getRequestFileInputStream(_) >> getObjectFromS3(fileName)
someHelper.someParser = Mock(SomeParser) {
....
}
Request requestInstance = new Request()
request.filename = fileName
request.fileType = fileType
expect:
someHelper.fooBar(requestInstance).getText == returnVal
where:
fileType | fileName | returnVal
"PDF" | "somepdf.pdf" | "somereturnval"
}
}
但是,上面的方法不起作用,因为它仍在尝试调用 SomeHelper
中 getRequestFileInputStream
的原始实现,而不是使用规范中提供的模拟实现。
你可以使用间谍
def someHelper = Spy(SomeHelper)
someHelper.getRequestFileInputStream(_) >> getObjectFromS3(fileName)
见Spies。
您可以使用真实的对象,但使用重写的方法:
given:
someHelper = new SomeHelper() {
@Override
InputStream getRequestFileInputStream(String filename) {
return getObjectFromS3(fileName)
}
}