3

Groovy is a wonderful language that offers lots of different choices.

In thinking about unit tests, when does it make sense to use an Expando object vs. the "as" operator with closures?

http://groovy.codehaus.org/Developer+Testing+using+Maps+and+Expandos+instead+of+Mocks vs http://groovy.codehaus.org/Developer+Testing+using+Closures+instead+of+Mocks

For simple cases, their use seems so similar.

Thanks!

finneycanhelp
  • 9,018
  • 12
  • 53
  • 77
  • The System Under Test (SUT) has dependencies. We mock out a dependency often using a map and then type it using the "as" operator. As said in the article "Developer Testing using Closures instead of Mocks", we use a "map of closures with the key used being the same name as the methods of the interface" In this case, the "interface" is the api of the dependency; it's a groovy/java class and not a groovy/java Interface. – finneycanhelp Jan 17 '11 at 16:59

1 Answers1

4

As noted on the page you referenced regarding using Closures instead of mocks, by themselves they only work for mocking interfaces and only if that interface has a single method. So if the class under test is not using an interface or you need to mock more than a single method you need to use either an Expando or Map. I prefer to be consistent and always use a Map, the code I deal with rarely needs objects mocked with a single interface method and using a Map does not require that many more keystrokes.

interface Foo {
    def someMethod(s)
}

// Closure, this breaks if someOtherMethod() is added to Foo or if Foo is a class
def mockMethod = { arg -> ...}
def myTestObject = new ObjectUnderTest(mockMetod as Foo)

// Map
def mockMethod = { arg -> ...}
def myTestObject = new ObjectUnderTest([someMethod:mockMethod] as Foo)

Not sure there is a significant difference between using a Map or Expando to mock an object, but I prefer a Map just because of the nice way you can declare a Map literal and not have to new up an Expando.

John Wagenleitner
  • 10,967
  • 1
  • 40
  • 39