Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Mocking using Map coercion

When using Java, Dynamic mocking frameworks are very popular. A key reason for this is that it is hard work creating custom hand-crafted mocks using Java. Such frameworks can be used easily with Groovy if you choose (as shown in this extended example) but creating custom mocks is much easier in Groovy. You can often get away with simple maps or closure to build your custom mocks.

Let's consider maps first.

By using maps or expandos, we can incorporate desired behaviour of a collaborator very easily as shown here:

Code Block
def service = [retrieveRate:{ new ExchangeRate(1.45, 0.57) }] as ExchangeRateService
def sterlingConverter = new SterlingCurrencyConverter(service)
double convertedAmount = sterlingConverter.convertFromSterling(10.0, Currency.USD);
assert convertedAmount == 14.50

For more details, see Developer Testing using Maps and Expandos instead of Mocks.

Mocking using Closure coercion

Alternatively, we can use closures:

Code Block
service = { new ExchangeRate(1.55, 0.56) } as ExchangeRateService
sterlingConverter = new SterlingCurrencyConverter(service)
convertedAmount = sterlingConverter.convertFromSterling(10.0, Currency.USD);
assert convertedAmount == 15.50

For more details, see Developer Testing using Closures instead of Mocks.

Mocking using MockFor and StubFor

If we need the full power of a dynamic mocking framework, Groovy has a built-in framework which makes use of meta-programming to define the behaviour of the collaborator. An example is shown here:

Code Block
import groovy.mock.interceptor.*

def mockContextClass = new MockFor(DummyExchangeRateService)
mockContextClass.demand.retrieveRate(1){ new ExchangeRate(1.65, 0.55) }
class DummyExchangeRateService implements ExchangeRateService {
    ExchangeRate retrieveRate(Currency currency){}
}
mockContextClass.use {
    def dummyService = new DummyExchangeRateService()
    sterlingConverter = new SterlingCurrencyConverter(dummyService)
    convertedAmount = sterlingConverter.convertFromSterling(10.0, Currency.USD)
    assert convertedAmount == 16.50
}

...

Instance-style MockFor and StubFor

You can also use MockFor and StubFor in a more traditional style by creating instances as follows:

Code Block
mockContext1 = new MockFor(ExchangeRateService)
mockContext1.demand.retrieveRate(1){ new ExchangeRate(1.75, 0.54) }
def dummyService1 = mockContext1.proxyInstance()
def sterlingConverter1 = new SterlingCurrencyConverter(dummyService1)
convertedAmount1 = sterlingConverter1.convertFromSterling(10.0, Currency.USD)
assert convertedAmount1 == 17.50

mockContext2 = new MockFor(ExchangeRateService)
mockContext2.demand.retrieveRate(1){ new ExchangeRate(1.85, 0.53) }
def dummyService2 = mockContext2.proxyInstance()
def sterlingConverter2 = new SterlingCurrencyConverter(dummyService2)
convertedAmount2 = sterlingConverter2.convertFromSterling(10.0, Currency.USD)
assert convertedAmount2 == 18.50