Reputation: 123
I'm writing groovy unit test and using Map coercion, I'm trying to figure out how to define a mock using a map, but then later in the test I want to add a method on the fly outside of the def statement. Is this possible?
Consider the following class.
class MapMockedClass{
String aMethod() {
return "original A method";
}
String bMethod( String str ) {
return "original B method with parameter ${str}";
}
}
I would like these tests to pass. See the test_Map_AddC, that's the one I can't figure out.
void test_Map_Original() {
def mock = new MapMockedClass()
assertEquals( "original A method", mock.aMethod() );
assertEquals( "original B method with parameter test", mock.bMethod("test") );
}
void test_Map_OverrideA() {
def mock = [ aMethod: "new A method" ] as MapMockedClass
assertEquals( "new A method", mock.aMethod() );
assertEquals( "original B method with parameter test", mock.bMethod("test") );
}
void test_Map_OverrideB() {
def mock = [ aMethod: "new A method",
bMethod: { param -> return "new B method with parameter ${param}" as String }] as MapMockedClass
assertEquals( "new A method", mock.aMethod() );
assertEquals( "new B method with parameter test", mock.bMethod("test") );
}
void test_Map_AddC() {
def mock = [ aMethod: "new A method",
bMethod: { param -> return "new B method with parameter ${param}" as String }] as MapMockedClass
assertEquals( "new A method", mock.aMethod() );
assertEquals( "new B method with parameter test", mock.bMethod("test") );
// Here I want to add a cMethod to the mock, but its not clear how to do it outside of the definition.
//mock.inject( cMethod, { return "new C method" });
//mock[ cMethod ] = { return "new C method" };
//mock[ 'cMethod' ] = { return "new C method" };
assertEquals( "new C method", mock.cMethod("test") );
}
Here are the new working methods after the answer was posted.
void test_Map_AddC() {
def mock = [ aMethod: "new A method",
bMethod: { param -> return "new B method with parameter ${param}" as String }] as MapMockedClass
assertEquals( "new A method", mock.aMethod() );
assertEquals( "new B method with parameter test", mock.bMethod("test") );
// Here I want to add a cMethod to the mock, but its not clear how to do it outside of the definition.
mock.metaClass.cMethod = { return "new C method" };
assertEquals( "new C method", mock.cMethod("test") );
}
void test_Map_ModifyAandB() {
def mock = [ aMethod: "new A method",
bMethod: { param -> return "new B method with parameter ${param}" as String }] as MapMockedClass
assertEquals( "new B method with parameter test", mock.bMethod("test") );
// http://otherthanthink.blogspot.com/2012/08/how-to-override-groovy-instance-and.html
mock.metaClass.aMethod = { return "An override for method a" }
assertEquals( "An override for method a", mock.aMethod() );
// Make sure you declare the String here otherwise it can't find the method.
mock.metaClass.bMethod = { String param -> return "second B method with parameter ${param}" as String };
assertEquals( "second B method with parameter foo", mock.bMethod("foo") );
}
Upvotes: 0
Views: 49
Reputation: 50285
cMethod
has to be added to the metaClass
of MapMockedClass
.
mock.metaClass.cMethod = { String arg -> return "new C method" }
Above line should be used before the assertion.
Upvotes: 2