The Promise class has a lot of methods. One of the methods is the time method. We can invoke this method an a Promise instance. The method creates a Duration object that we can use inside the method. The duration is the time taken from when the promise is subscribed to to when the result is available. The promise value is not changed, so we can add the time method at any position of a method chain for the Promise object.

In the following specification we check the duration for a Promise that is returned by the method generate of the class Numbers. For our example we wait for a number of seconds dependent on the argument of the generate method. In the specification we use the time method and check the time spent to fulfil the promise.

package mrhaki.ratpack

import ratpack.exec.Promise

import ratpack.test.exec.ExecHarness
import spock.lang.Specification
import spock.lang.Unroll

import java.time.Duration

class NumbersSpec extends Specification {

    @Unroll('with argument #num response time should be at least #responseTime')
    void 'time used by Numbers.generate method increased and dependent on argument'() {
        given:
        final numbers = new Numbers()

        and:
        long timer

        when:
        final result = ExecHarness.yieldSingle {
            numbers.generate(num)
                   .map { value -> value - 1 }
                   .time { duration -> timer = duration.toMillis() }
        }

        then:
        timer >= responseTime
        result.value == generateResult

        where:
        num | responseTime | generateResult
        1   | 1_000        | 0
        2   | 2_000        | 3
        10  | 10_000       | 99
    }

}

class Numbers  {
    Promise generate(final Long multiplier) {
        Promise
            .sync { ->
                 // Wait for n-seconds...
                 sleep(multiplier * 1000)
                 multiplier
            }
            .map { value ->
                value * value
            }
    }
}

Written with Ratpack 1.4.5.

shadow-left