Use Case
It's useful to test exception handling. In this specific case, I have a extractor that will do a specific task when an exception is thrown while unmarshaling a specific class.
The signature of the method that I want to mock is:
public <T> T unmarshaler(Node element, Class<? extends T> type) throws TransformException
Things I've Tried
Here's a list of things I've tried. For brevity, I haven't filled in all the mundane details.
Spying
The following method doesn't do anything and the exception doesn't throw. I'm not sure why.
XmlMarshaler spiedXmlMarshaler = Mockito.spy(fixture.xmlMarshaler);
doThrow(new TransformException( ... )).when(spiedXmlMarshaler)
.unmarshal(any(), eq(SpecificThing.class));
Mocking
The following didn't work because partial mocks don't seem to play well with methods that throw exceptions. Instead, it passes the arguments null
, null
to the real method each time.
XmlMarshaler mockXmlMarshaler = mock(XmlMarshaler.class);
Mockito.when(mockXmlMarshaler.unmarshal(any(), any())).thenCallRealMethod();
Mockito.when(mockXmlMarshaler.unmarshal(any(), eq(SpecificThing.class))
.thenThrow(new TransformException(...));
ThenAnswer
This works, but I'm not sure if it's the proper way to do this:
final XmlMarshaler realXmlMarshaler = new XmlMarshaler();
XmlMarshaler mockXmlMarshaler = Mockito.mock(XmlMarshaler.class);
fixture.xmlMarshaler = mockXmlMarshaler;
Mockito.when(mockXmlMarshaler.unmarshal(any(), any())).thenAnswer(new Answer() {
@SuppressWarnings({ "unchecked" })
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
Node node = (Node)args[0];
Class clazz = (Class)args[1];
if (clazz.equals(SpecificThing.class)) {
throw new TransformException(...);
}
return realXmlMarshaler.unmarshal(node, clazz);
}
});
Question
Although the thenAnswer
method works, it doesn't seem to be the proper solution. What is the correct way to perform a partial mock for this situation?
Aucun commentaire:
Enregistrer un commentaire