Thursday, July 2, 2009

GMock: Mocking Property Setting via a setProperty() Method

Below is a Java method I wanted to mock using GMock. The class under test is validating an incoming message in a Mule container. The features and properties passed into the set methods below are static in the class under test, OrderValidationRouter.
    private void setSchemaValidationFeatures(SAXReader reader) throws Exception {
reader.setValidation(true);
reader.setFeature(VALIDATION_SCHEMA, true);
reader.setFeature(VALIDATION_SCHEMA_FULL_CHECKING, true);
reader.setProperty(SCHEMA_LANGUAGE, SCHEMA_LANGUAGE_VALUE);
reader.setProperty(SCHEMA_SOURCE, getXsdAsStream());
}
My first attempt at testing the method with GMock:
@WithGMock
class OrderValidationRouterTest {

OrderValidationRouter router

@Before
void setUp() {
router = new OrderValidationRouter()
}

@Test
void testSettingSchemaValidationFeatures() {
def readerMock = mock(SAXReader)
def xsdStream = new ByteArrayInputStream()

router.setXsdAsStream(xsdStream)

readerMock.setValidation(true)
readerMock.setFeature(
OrderValidationRouter.VALIDATION_SCHEMA, true)
readerMock.setFeature(
OrderValidationRouter.VALIDATION_SCHEMA_FULL_CHECKING, true)
readerMock.setProperty(OrderValidationRouter.SCHEMA_LANGUAGE,
OrderValidationRouter.SCHEMA_LANGUAGE_VALUE)
readerMock.setProperty(OrderValidationRouter.SCHEMA_SOURCE, xsdStream)

play {
router.setSchemaValidationFeatures(readerMock)
}
}
}
The test worked fine with the exception of the setProperty() expectations, producing the following test failure:
junit.framework.AssertionFailedError: Unexpected property setter call 
'"http://java.sun.com/xml/jaxp/properties/schemaLanguage" =
"http://www.w3.org/2001/XMLSchema"'
Turns out I need to mock the actual setting of the property and not the method call. There are several ways to do this, but I went with the first thing that came to mind:
   def property = OrderValidationRouter.SCHEMA_LANGUAGE
def value = OrderValidationRouter.SCHEMA_LANGUAGE_VALUE
readerMock."$property".set(value)

property = OrderValidationRouter.SCHEMA_SOURCE
value = xsdStream
readerMock."$property".set(value)

The property variable needs to be interpolated in a GString or else the mock will be expecting for a property named property to be set.

If you have any alternatives, feel free to post them, thanks

1 comment:

  1. This looks like a bug to me, please raise an issue on http://code.google.com/p/gmock/issues/list.

    ReplyDelete