Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock a single method for a class in Spock?

Tags:

groovy

spock

I have a method like below in my class that I'm trying to test:

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
    }
....
}

In the above, getRequestFileInputStream is a method that takes as parameter a name of the file. It fetches the inputstream of that file from AWS S3. While testing fooBar method from Spock, I would like to provide a mock for the getRequestFileInputStream method because I don't want to use the implementation of this method that is in the class since it goes to another bucket name.

Is it possible to do this?

Below is what I've tried:

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"
    }
}

However, the above doesn't work because it is still trying to call the original implementation of getRequestFileInputStream in SomeHelper instead of using the mocked implementation provided in the spec.

like image 989
Anthony Avatar asked Dec 01 '22 15:12

Anthony


1 Answers

You can use a real object but with overridden method:

given:
    someHelper = new SomeHelper() {
         @Override
         InputStream getRequestFileInputStream(String filename) {
             return getObjectFromS3(fileName)
         }
    }
like image 138
Dmytro Maslenko Avatar answered Dec 04 '22 23:12

Dmytro Maslenko